I am learning to use @property
decorators. I am giving two codes below with a little variation:
Code 1
class P2:
def __init__(self, x):
self.x = x
@property
def x(self):
return self.y
@x.setter
def x(self, x):
if x < 0:
self.y = x
elif x > 1000:
self.y = 1000
else:
self.y = x
p1 = P2(7600)
print(p1.y)
Code2
class P2:
def __init__(self, x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = x
elif x > 1000:
self.__x = 1000
else:
self.__x = x
p1 = P2(7600)
print(p1.__x)
To obtain the code2 I replace y
by __x
in code1. But the issue is that the code1 is running perfectly fine but the code2 is giving an error 'P2' object has no attribute '__x'
.
My understanding is that y
and __x
are merely two variables, they should behave in same way, so in my opinion code2 and code1 are identical and both should give same output.
But it is not happening, what is wrong in my understanding? Please help.
CodePudding user response:
Properties that are prepended with a double underscore are pseudo-private. (There is no notion of completely private variables in Python, unlike Java or C .)
To access pseudo-private member variables, replace the double underscore with _<name of your class>__
(i.e. an underscore, followed by the class name, followed by two underscores). That being said, if you need to do this, you should consider why the variable is pseudo-private in the first place.
class P2:
def __init__(self, x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = x
elif x > 1000:
self.__x = 1000
else:
self.__x = x
p1 = P2(7600)
print(p1._P2__x) # Prints 1000