简体   繁体   English

Python属性setter如何进行多级设置?

[英]Python property setter how to do multistage setting?

I have created two class A and B (use @property to get and set their attribute). 我创建了两个A和B类(使用@property来获取和设置它们的属性)。 class B has a member whose type is class A. How to set the attribute of bax ? B类有一个类型为A类的成员。如何设置bax的属性?

class A: 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

class B: 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 ?

Am I wrong with the using of @property ? 我使用@property错了吗?

Your code works fine but if you are looking for another approach you could inherit the A class and bax becomes bx . 你的代码工作正常,但如果你正在寻找另一种方法,你可以继承A类, bax变成bx

You can achieve this by adding the following line in B 's constructor 您可以通过在B的构造函数中添加以下行来实现此目的

super(A, self).__init__()

hence bax == bx 因此bax == bx

adding print() to your classes shows the behaviour, calling bax = 1 will make x.setter in A class in charge not a.setter in B class 将print()添加到您的类中会显示行为,调用bax = 1将使A类中的x.setter成为B类中的a.setter

example: 例:

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

output: 输出:

x.setter acting

if you want a.setter to be in charge you can: 如果你想让a.setter负责你可以:

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

output: 输出:

a.setter acting

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM