1

I'm editing some Python code containing the line:

arr = (c_double * len(self.static_mapped[0, :]))(*self.static_mapped[0, :])

where field self.static_mapped is created using numpy.zeros and where c_double is imported from ctypes.

Based on the context, I'm assuming this is typecasting from numpy doubles to C-type doubles, but this syntax doesn't appear in any of the Python guides I've consulted, and even my IDE is complaining that "'int' object is not callable".

Am I correct in my interpretation of its meaning? What sequence of function calls is going on under the hood? Is this a well-known code idiom in Python or is there a more standard/straightforward way of accomplishing this?

1 Answer 1

3

Strictly from a syntactic perspective, your code should be equivalent to

t = c_double * len(self.static_mapped[0, :])
arr = t(*self.static_mapped[0, :])

This implies that c_double.__mul__ is overridden to produce some other type object that gets called to produce an array. No type-casting, just dynamic type generation.

Specifically, multiplying type by an integer n creates an array of n values:

>>> c_double * 2
<class '__main__.c_double_Array_2'>
>>> c_double * 3
<class '__main__.c_double_Array_3'>
>>> c_double * 7
<class '__main__.c_double_Array_7'>

Note that "type multiplication" is not associative:

# An array of arrays
>>> c_double * 7 * 2
<class '__main__.c_double_Array_7_Array_2'>

# A single array
>>> c_double * (7 * 2)
<class '__main__.c_double_Array_14'>
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, I see! And the returned c_double_Array_X class has a constructor that accepts a variadic list of numpy double arguments. Got it. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.