将变量设置为对象时,将其设置为其中的所有嵌套对象

When setting variable to object, set it to all nested objects within

我有以下有效的代码:

class fundamental_object():

    def __init__(self,x):
        self.x = x

class encapsulator_object():

    def __init__(self,x,obj_list):
        self._x = x
        self.obj_list = obj_list

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

    @x.setter
    def x(self,new_x):
        print('in setter!')
        self._x = new_x
        for obj in self.obj_list:
            obj.x = new_x

if __name__ == '__main__' :
    x = 10
    obj_1 = fundamental_object(x)
    obj_2 = fundamental_object(x)
    obj_list = [obj_1,obj_2]
    encapsulator = encapsulator_object(x,obj_list)

    encapsulator.x = 20
    print(encapsulator._x)
    print(obj_1.x) # all of these are also updated to 20.

如您所见,我的想法是,每当我更改封装器对象的属性“x”时,我都希望其中的所有嵌套对象 (fundamental_objects) 也使用这个新变量进行更新“X”。但是,从用户的角度来看,这很快就会让人感到困惑,因为如果我理解正确的话,“x”是“fundamental_object”的整数,而“x”是“encapsulator_object”的方法,并且要实际访问封装器中的整数,我需要使用“_x”。有什么 easy/correct/pythonic 方法可以实现以下工作:

    x = 10
    obj_1 = fundamental_object(x)
    obj_2 = fundamental_object(x)
    obj_list = [obj_1,obj_2]
    encapsulator = encapsulator_object(x,obj_list)

    encapsulator.x = 20
    print(encapsulator.x) # notice the underscore is now gone!  
    print(obj_1.x)        # this would be updated to 20 as well

我知道可以让“fundamental_objects”也有“_x”作为整数变量,这会在一定程度上减少混乱,但我仍然想完全摆脱如果可能的话,下划线! (现在我得到了无限递归)。谢谢!

检查此代码。我只是在您的 属性 中更改了您的 getter 方法。现在它指向 self._x.

class fundamental_object():
    def __init__(self, x):
        self.x = x


class encapsulator_object():
    def __init__(self, x, obj_list):
        self._x = x
        self.obj_list = obj_list

    @property
    def x(self):
        return self._x   # -----> here

    @x.setter
    def x(self, new_x):
        print('in setter!')
        self._x = new_x
        for obj in self.obj_list:
            obj.x = new_x


if __name__ == '__main__':
    x = 10
    obj_1 = fundamental_object(x)
    obj_2 = fundamental_object(x)
    obj_list = [obj_1, obj_2]
    encapsulator = encapsulator_object(x, obj_list)

    encapsulator.x = 20
    print(encapsulator.x)  # notice the underscore is now gone!
    print(obj_1.x)  # this would be updated to 20 as well

作为替代方案,您可以完全删除 encapsulator_object 中的 x_x。然后在 getter 中,您可以在 self.obj_list 中找到 x :

class fundamental_object():
    def __init__(self, x):
        self.x = x


class encapsulator_object():
    def __init__(self, obj_list):
        self.obj_list = obj_list

    @property
    def x(self):
        return self.obj_list[0].x

    @x.setter
    def x(self, new_x):
        print('in setter!')
        for obj in self.obj_list:
            obj.x = new_x

请记住,在本例中,因为我们决定选择列表中的第一项,所以所有对象都必须具有相同的 x 值。可以 setter 之后就不用担心了。如果您想在 setter.

之前调用 getter,我提到过它