pythonnumpyctypesidioms

Is this Python code a kind of typecast, and, if so, what is going on under the hood?


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?


Solution

  • 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'>