Python 将变量设置为对象时,请将其设置为中的所有嵌套对象
我有以下有效的代码:Python 将变量设置为对象时,请将其设置为中的所有嵌套对象,python,oop,attributes,decorator,python-decorators,Python,Oop,Attributes,Decorator,Python Decorators,我有以下有效的代码: 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
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”时,我都希望其中的所有嵌套对象(基本对象)也用这个新变量“x”更新。然而,从用户的角度来看,这很快就会令人困惑,因为如果我理解正确,“x”是“基本对象”的整数,而“x”是“封装器对象”的方法,要实际访问封装器中的整数,我需要使用“\x”。是否有任何简单/正确/通灵的方法来实现以下功能:
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
我知道有可能使“基本对象”也有“\ux”作为整数变量,这会在一定程度上减少混淆,但是,如果可能的话,我想完全去掉下划线!(现在我得到一个无限递归)。谢谢 检查此代码。我只是在你的属性中更改了你的getter方法。现在它指向
自身
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
或者,您可以完全删除封装器\u对象
中的x
或\u x
。然后在getter中,您可以在self.obj_列表中找到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之前调用getter,我提到了它。您的封装器\u object.x
属性是无限递归的。你的意思是“回归自我”。谢谢你的回答。事实上,第一个是有效的,所以我接受它作为一个答案。然而,我仍然有一部分人觉得很难说服用户需要下划线(如果他们决定输入代码)。它的目的是什么?它只是一个中间变量,允许setter方法执行我想要的操作?@Zepphit第二部分也可以,只需从enclosurator=enclosurator\u对象(x,obj\u列表)
中删除x
,因为它不再需要了。我们消除了x
。如果确保传递到列表中的所有对象都具有相同的x
属性,则使用第二个属性。如果没有,请确保先调用设置器
,然后再调用第二个设置器。这里没有下划线,谢谢,但是由于self.obj_列表[0].x部分,我觉得使用第二种方法不舒服。我仍然希望封装器_对象本身有自己的“变量”,而不是引用它们自己对象中的变量。另一个在外面会更好,但在我看来仍然不理想。。。