Python属性设置器如何进行多阶段设置?

时间:2019-05-08 02:37:42

标签: python

我创建了两个类A和B(使用@property获取并设置它们的属性)。 B类的成员类型为A类。如何设置b.a.x的属性?

A类:

class A(object):
    def __init__(self, x=0, y=0):
        self._x = x
        self._y = y

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = value

B级:

class B(object):
    def __init__(self):
        self._a = A()

    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        if isinstance(value, A):
            self._a = deepcopy(value)
        elif isinstance(value, tuple):
            self._a = A(value[0], value[1])
        elif isinstance(value, int):
            # ?           
            pass
b = B()
b.a.x = 1 # How to implementate this ?

我使用@property错了吗?

2 个答案:

答案 0 :(得分:0)

您的代码可以正常工作,但是如果您正在寻找其他方法,则可以继承A类,并且b.a.x变成b.x

您可以通过在B的构造函数中添加以下行来实现这一点

super(A, self).__init__()

因此 b.a.x == b.x

答案 1 :(得分:0)

在您的班级中添加print()会显示该行为,调用b.a.x = 1将使A级负责人中的x.setter而不是B级主管中的a.setter。

示例:

class A(object)
    .
    .
    @x.setter
    def x(self, value):
        print('x.setter acting')
        self._x = value


class B(object):
    .
    .
    @a.setter
    def a(self, value):
        print('a.setter acting')  # adding print 
        if isinstance(value, A):
            self._a = deepcopy(value)
        elif isinstance(value, tuple):
            self._a = A(value[0], value[1])
        elif isinstance(value, int):
            # ?           
            pass

b = B()
b.a.x = 1 # x.setter will be in charge not a.setter

输出:

x.setter acting

如果您希望由接管员负责,您可以:

class B(object):
        .
        .
        @a.setter
        def a(self, value):
            print('a.setter acting')  # adding print 
            if isinstance(value, A):
                self._a = deepcopy(value)
            elif isinstance(value, tuple):
                self._a = A(value[0], value[1])
            elif isinstance(value, int):
                # ?           
                self._a.x = value

b = B()
b.a = 1 # a.setter will be in charge

输出:

a.setter acting