python-3.xnumpymetaclassdtypestructured-array

Creating own type from numpy.dtype for structured array. What is the cleanest way to obtain this?


I would like to derive an own class from numpy.dtype like this:

import numpy as np
class A(np.dtype):
    def __new__(cls):
        cls.fields = [("field1", np.int32), ("field2"), np.int64)]

However, numpy won't let me do this:

type 'numpy.dtype' is not an acceptable base type

Therefore i started fiddling around with metaclasses. However, my code makes no use of name, bases, dct. Is this principally OK? I mean, it works but is it a good way to do this?

class NumpyDType_Meta(type):
    def __new__(cls, name, bases, dct, **args):
        return np.dtype(**args)
    
class A(metaclass = NumpyDType_Meta, 
        dtype = [("field1", np.int32), ("field2"), np.int64)]):
    pass


arr = np.array([[1,2],[3,4]], dtype = A)


arr
array([[(1, 1), (2, 2)],
       [(3, 3), (4, 4)]], dtype=[('field1', '<i4'), ('field2', '<i8')])

Solution

  • You don't need to create another "dtype" class there - just a dtype instance.

    And your journey through metaclass land, in fact, do just that - as your __new__ method returns a dtype instance, that is what replaces the class A statement in your body. As ou pass **args to dtype constructor, and you have your specification passed as a "dtype" keyword argument to the class, it happens to work.

    But all your code up to the declaration of arr is the same as doing simply:

    A = np.dtype([("field1", np.int32), ("field2", np.int64)]) 
    

    That creates a new dtype with your subfields and it is really all you need.