Может быть, метаклассы ctypes просто не будут хорошо работать, будучи подклассами - поскольку он сам написан на C, он может обойти маршруты наследования для некоторых сочетаний клавиш и привести к сбоям.
В идеале это «плохое поведение» должно быть надлежащим образом документировано, заполнено ошибками в ctypes CPython и исправлено - насколько мне известно, не так много людей могут исправить ошибки ctypes.
С другой стороны, иметь метакласс только потому, что вы хотите подобный атрибуту свойства на уровне класса, излишне.
Python property
сам по себе является просто готовым, очень полезным встроенным классом, который реализует протокол дескриптора .Любой класс, который вы создаете самостоятельно и который реализует надлежащие методы __get__
и __set__
, может заменить «свойство» (и часто, когда логика разделяется между атрибутами-свойством, приводит к более короткому, не дублированному коду)
Наво-вторых, к сожалению, установщики дескрипторов будут работать только для экземпляров, а не для классов (что имеет смысл, поскольку выполнение cls.attr
уже даст вам специальное значение с кодовой защитой, и нет способа вызвать метод __set__
Итак, если бы вы могли работать с «ручным» заданием значений в cls.__dict__
и помещением логики в атрибут __get__
, вы могли бы сделать:
PREFIX = "_cls_prop_"
class ClsProperty:
def __set_name__(self, owner, name):
self.name = name
def __get__(self, instance, owner):
value = owner.__dict__.get(PREFIX + self.name)
# Logic to transform/check value goes here:
if not isinstance(value, list):
raise TypeError('some_param must be a list')
return value
def b_function(some_param_arg):
class c_class(ctypes._CFuncPtr):
_argtypes_ = ()
_restype_ = None
_flags_ = 0 # ctypes._FUNCFLAG_STDCALL # change for CFUNCTYPE or WINFUNCTYPE etc ...
_some_param_ = ClsProperty()
setattr(c_class, PREFIX + "_some_param_", some_param_arg)
return c_class
d_class = b_function([1, 2, 3])
print(d_class._some_param_)
d_class._some_param_ = [1, 2]
print(d_class._some_param_)
Если это не сработает, я не думаю, что другие подходы, пытающиеся расширить метакласс CTypes, будут работать в любом случае, но если вы хотите попробовать, вместо «мета-свойства», вы можете попытаться настроить метакласс '__setitem__
вместо этого, чтобы сделать проверку параметров, вместо использования property
.