我有一个类,其中包含其他类的实例:
from ctypes import *
class C():
A = propA()
B = propB()
def __init__(self):
class c_struct(Structure):
_fields_ = [('_A', c_int), ('_B', c_int)]
self._c_struct = c_struct()
我需要做的是某种方式" connect"在propA
中创建的内部结构propB
的{{1}}和_c_struct
类最终会获得如此行为:
C
c = C()
c.A.val = 12
c.B.val = 13
c._c_struct._A == c.A.val == 12
能够操纵C.A
的地方。我试图做这样的事情:
C._c_struct._A
但似乎from ctypes import *
class propParent():
def set_ref(self, ext_ref):
self._val = ext_ref
@property
def val(self):
return self._val
@val.setter
def val(self, val):
self._val = val
class propA(propParent):
# further definition here
pass
class propB(propParent):
# further definition here
pass
class C():
A = propA()
B = propB()
def __init__(self):
class c_struct(Structure):
_fields_ = [('_A', c_int), ('_B', c_int)]
self._c_struct = c_struct()
self.A.set_ref(self._c_struct._A)
self.B.set_ref(self._c_struct._B)
返回一个python整数对象,而不是对结构的self._c_struct._A
内部c_int对象的引用。如何将属性连接到同一类中另一个属性的子属性?
答案 0 :(得分:1)
这似乎适合descriptor,field c_struct._A
is also:
In [3]: c_struct._A
Out[3]: <Field type=c_int, ofs=0, size=4>
In [4]: c_struct._A.__get__
Out[4]: <method-wrapper '__get__' of _ctypes.CField object at 0x7f967303cf48>
这就是为什么在通过int
实例而不是字段本身访问时返回c_struct
的原因。首先定义一个适合您的用例:
class prop:
def __init__(self, name):
self.name = name
def __repr__(self):
return 'prop({!r})'.format(self.name)
def __get__(self, instance, owner):
if not instance:
return self
return getattr(instance._c_struct, '_{}'.format(self.name))
def __set__(self, instance, value):
setattr(instance._c_struct, '_{}'.format(self.name), value)
或只是
def prop(name):
name = '_{}'.format(name)
return property(
lambda self: getattr(self._c_struct, name),
lambda self, value: setattr(self._c_struct, name, value))
然后定义原始类:
class C:
A = prop('A')
B = prop('B')
def __init__(self):
class c_struct(Structure):
_fields_ = [('_A', c_int), ('_B', c_int)]
self._c_struct = c_struct()
测试:
In [36]: c = C()
In [37]: c.A
Out[37]: 0
In [38]: c._c_struct._A
Out[38]: 0
In [39]: c.A = 12
In [40]: c._c_struct._A
Out[40]: 12
要获得额外的功劳,如果您使用的是最新版本的Python,则可以使用object.__set_name__()
来删除复制名称的需要,而无需使用元类:
class prop:
def __init__(self, name=None):
self.name = name
def __set_name__(self, owner, name):
if self.name is None:
self.name = name
...
然后将C定义为:
class C:
A = prop()
B = prop()
...