2

In this example, a user can still access and set the variable using:

obj = C()
obj._x=10
varA  = obj._x

Even if we use __x instead of _x in below code, x still doesn't become private. So the only purpose of _x is to let the programmers know that it is not meant to be set directly via obj._x?

class C:
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x
6
  • 8
    No. Python is a language for "consenting adults"; that is, we may indicate that a variable is private via a leading underscore, but we don't enforce privacy like C++/C#/Java. The double leading underscore has a specific purpose: mimicking the access modifiers in other languages is not that purpose. Commented Sep 9, 2019 at 19:15
  • Even a leading double underscore won't prevent modification, it will just make it "harder" stackoverflow.com/questions/1301346/…
    – DeepSpace
    Commented Sep 9, 2019 at 19:17
  • Python doesn't have private. Not even double-underscore name-mangling. That isn't what double-underscore name-mangling is for. Your example using property is not what you should be doing. Commented Sep 9, 2019 at 19:19
  • Ok so in this example, the purpose of property is to ensure that when value is assigned or fetched using obj.x, then, it calls the appropriate getter/setter which will apply logic if any and then get/set the value from/to _x respectively
    – variable
    Commented Sep 9, 2019 at 19:36
  • @variable And in that case, you should (probably) be assigning to the property everywhere, even in __init__, instead of bypassing and assigning directly to _x.
    – chepner
    Commented Sep 9, 2019 at 19:39

1 Answer 1

3

In Python, it is a convention to use _var_name in order to indicate that something is private, but it does not enforce it like in languages as C++, C#, Java, etc.

A double underscore prefix causes the Python interpreter to rewrite the attribute name in order to avoid naming conflicts in subclasses.

This is also called name mangling—the interpreter changes the name of the variable in a way that makes it harder to create collisions when the class is extended later.

Consider the following example

class Test:
    def __init__(self):
        self.foo = 11
        self._bar = 23
        self.__baz = 23

Now, let's run the following code:

>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
 '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
 '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
 '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
 '__weakref__', '_bar', 'foo']

dir(t) gives us a list with the object’s attributes. When you search for __baz in that list you’ll see that there is no variable with that name. If you look closely you’ll see there’s an attribute called _Test__baz on this object. This is the name mangling that the Python interpreter applies.

7
  • Ok so even removing the single underscore doesnt make any difference technically
    – variable
    Commented Sep 9, 2019 at 19:23
  • @variable, it doesn't. As user snakecharmerb has told you. This is an agreed convention, so you can simply break the rules, but Pythonistas has agreed to respect it. Commented Sep 9, 2019 at 19:25
  • 2
    @variable Again, Python does not have private variables. It says that right in the documentation. If you are looking for that, use another language Commented Sep 9, 2019 at 19:25
  • @juanpa.arrivillaga, thank you so much to provide links to the documentation. Commented Sep 9, 2019 at 19:29
  • The purpose of property is to ensure that when value is assigned or fetched using obj.x, then, it calls the appropriate getter/setter which will apply logic if any and then get/set the value from/to _x respectively ?
    – variable
    Commented Sep 9, 2019 at 19:42

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.