Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is `self.__x` not working but `self.y` is?

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But it is not happening, what is wrong in my understanding? Please help.

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading