Reputation: 61
I have the following code that works:
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.
As you can see, the idea is that, whenever I change the attribute "x" of the encapsulator object, I want all nested objects inside it (fundamental_objects) to also be updated with this new variable "x". However, from a user standpoint, this gets confusing really quickly, since, if I understand correctly, "x" is an integer for "fundamental_object", whereas "x" is a method for "encapsulator_object", and to actually access the integer in the encapsulator I would need to use "_x". Is there any easy/correct/pythonic way to make it so the following works :
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
I understand that it is possible to make it so "fundamental_objects" also have "_x" as the integer variable, which would somewhat reduce the confusion, but still, I'd like to completely get rid of the underscores if possible! (right now I get an infinite recursion). Thanks!
Upvotes: 0
Views: 355
Reputation: 16536
Check this code. I only changed your getter method in your property. Now it is pointing to the 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
As an alternative you can completely remove x
or _x
in encapsulator_object
. Then in your getter you can find x
within the self.obj_list
:
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
Bear in mind that, in this example because we decided to pick first item in the list, all objects must have the same x
value. There is no need to worry about it after you can the setter though. I mentioned it if you want to call the getter before setter.
Upvotes: 1