如何在python类中将引用从一个属性传递到另一个属性?

时间:2017-11-07 04:53:39

标签: python

我有一个类,其中包含其他类的实例:

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对象的引用。如何将属性连接到同一类中另一个属性的子属性?

1 个答案:

答案 0 :(得分:1)

这似乎适合descriptorfield 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()

    ...