Default values in a ctypes Structure

2019-06-17 09:44发布

问题:

In a ctypes Structure, is it possible to specify default values?

For example, with a regular python function, you can do this:

def func(a, b=2):
    print a + b

That would allow for this behaviour:

func(1) # prints 3

func(1, 20) # prints 21

func(1, b=50) # prints 51

Is it possible to do this in a ctypes Structure?

for example:

class Struct(Structure):
    _fields_ = [("a", c_int), ("b", c_int)] # b default should be 2

    def print_values(self):
        print self.a, self.b

struct_instance = Struct(1)

struct_instance.print_values() # should somehow print 1, 2

回答1:

Yes. Simply override the __init__ method.

class Struct(Structure):
    _fields_ = [("a", c_int), ("b", c_int)]

    def __init__(self, a, b=2):
        super(Struct, self).__init__(a, b)

    def print_values(self):
        print(self.a, self.b)


回答2:

There is a more comfortable way if you have a lot of structures with default values different to ctypes' ones. Expand the ctypes.Structure to another class variable _defaults_.

class BaseStructure(ctypes.Structure):

    def __init__(self, **kwargs):
        """
        Ctypes.Structure with integrated default values.

        :param kwargs: values different to defaults
        :type kwargs: dict
        """

        values = type(self)._defaults_.copy()
        for (key, val) in kwargs.items():
            values[key] = val

        super().__init__(**values)            # Python 3 syntax



class YourStructure(BaseStructure):
    _fields_ = [ ("param1", ctypes.c_uint32),
                 ("param2", ctypes.c_uint32),
                 ("param3", ctypes.c_int32),
               ]
    _defaults_ = { "param1" : 42,
                   "param3" : -23,
                 }