4

I am trying to creating a python array and have problems with the following code

def __init__(self, size):
    assert size>0, "Array size must be > 0"
    self._size = size
    # Create the array structure using the ctypes module.

    arraytype = ctypes.py_object * size
    self._elements = arraytype()

In the initialization, it uses ctypes to create an array and I don't really understand the last two lines. I tried to change them into one line

self._elements = ctypes.py_object() * size

But it doesn't work and gives me the error

TypeError: unsupported operand type(s) for *: 'py_object' and 'int'

Could anyone explain it for me?

NellieK
  • 131
  • 1
  • 6
Charlotte
  • 43
  • 1
  • 4
  • To combine those two lines into one you'd do `self._elements = (ctypes.py_object * size)()`. But why are you using `ctypes` to create an array? – PM 2Ring Jun 16 '18 at 17:31
  • BTW, you normally raise `ValueError` when a function or method is passed invalid args. `assert` shouldn't be used to detect bad data, it should only be used to detect faulty logic in your program. That is, if `AssertionError` is raised that means the program is broken and needs to be fixed. But I guess that may be what it _is_ doing in this particular case. – PM 2Ring Jun 16 '18 at 17:35

3 Answers3

4
  • ctypes.py_object is a type
  • ctypes.py_object * size is a type
  • ctypes.py_object() is an instance of a type

What you want to do is take the ctypes.py_object * size type first, and then instantiate it:

self._elements = (ctypes.py_object * size)()

Although you probably want to go with a Python list, I'm not sure you need a ctypes array. Example:

self._elements = [None] * size
Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
  • Another option is an [`array.array`](https://docs.python.org/3/library/array.html#module-array), although they are restriceted to simple numeric types & strings. And it looks like the OP wants an array of generic `py_object`s; perhaps they're interacting with some Python-aware C interface... – PM 2Ring Jun 16 '18 at 17:39
  • I am wondering what why we can multiply some type with an integer. What does it mean? – Charlotte Jun 16 '18 at 17:43
  • 2
    @Charlotte: multiplying a ctype with an integer is declaring an array. `ctypes.c_int * 4` is an array of 4 integers – Andrea Corbellini Jun 16 '18 at 19:39
  • Thanks. It helps a lot. So can I say this kind of operation only works for ctype because I try to multiply an integer with other types(eg.list,int,etc) but it will deliver the error "unsupported operand type(s) for :"? – Charlotte Jun 17 '18 at 15:16
  • @Charlotte: yes, it only works with ctypes. Builtin types (int, str, list, tuple, ...) don't support multiplication. Of course there might be other libraries that supports this feature, but this is not the case for builtin types. – Andrea Corbellini Jun 17 '18 at 16:17
0

you want to mutiple with () simple remove parentheses and it will work

self._elements = ctypes.py_object * size
Druta Ruslan
  • 7,171
  • 2
  • 28
  • 38
0

This will work self._elements = (size*ctypes.py_object)( )

  • While code-only answers might answer the question, you could significantly improve the quality of your answer by providing context for your code, a reason for why this code works, and some references to documentation for further reading. Brevity is acceptable, but fuller explanations are better – Pranav Hosangadi May 10 '22 at 21:27