Python name mangling

2018-12-31 14:40发布

In other languages, a general guideline that helps produce better code is always make everything as hidden as possible. If in doubt about whether a variable should be private or protected, it's better to go with private.

Does the same hold true for Python? Should I use two leading underscores on everything at first, and only make them less hidden (only one underscore) as I need them?

If the convention is to use only one underscore, I'd also like to know the rationale.

Here's a comment I left on JBernardo's answer. It explains why I asked this question and also why I'd like to know why Python is different from the other languages:

I come from languages that train you to think everything should be only as public as needed and no more. The reasoning is that this will reduce dependencies and make the code safer to alter. The Python way of doing things in reverse -- starting from public and going towards hidden -- is odd to me.

9条回答
听够珍惜
2楼-- · 2018-12-31 15:33

At first glance it should be the same as for other languages (under "other" I mean Java or C++), but it isn't.

In Java you made private all variables that shouldn't be accessible outside. In the same time in Python you can't achieve this since there is no "privateness" (as one of Python principles says - "We're all adults"). So double underscore means only "Guys, do not use this field directly". The same meaning has singe underscore, which in the same time doesn't cause any headache when you have to inherit from considered class (just an example of possible problem caused by double underscore).

So, I'd recommend you to use single underscore by default for "private" members.

查看更多
与君花间醉酒
3楼-- · 2018-12-31 15:39

Following code snippet will explain all different cases :

  • two leading underscores (__a)
  • single leading underscore (_a)
  • no underscore (a)

    class Test:
    
    def __init__(self):
        self.__a = 'test1'
        self._a = 'test2'
        self.a = 'test3'
    
    def change_value(self,value):
        self.__a = value
        return self.__a
    

printing all valid attributes of Test Object

testObj1 = Test()
valid_attributes = dir(testObj1)
print valid_attributes

['_Test__a', '__doc__', '__init__', '__module__', '_a', 'a', 
'change_value']

Here, you can see that name of __a has been changed to _Test__a to prevent this variable to be overridden by any of the subclass. This concept is known as "Name Mangling" in python. You can access this like this :

testObj2 = Test()
print testObj2._Test__a

test1

Similarly, in case of _a, the variable is just to notify the developer that it should be used as internal variable of that class, the python interpreter won't do anything even if you access it, but it is not a good practise.

testObj3 = Test()
print testObj3._a

test2

a variable can be accesses from anywhere it's like a public class variable.

testObj4 = Test()
print testObj4.a

test3

Hope the answer helped you :)

查看更多
长期被迫恋爱
4楼-- · 2018-12-31 15:46

The chosen answer does a good job of explaining how properties remove the need for private attributes, but I would also add that functions at the module level remove the need for private methods.

If you turn a method into a function at the module level, you remove the opportunity for subclasses to override it. Moving some functionality to the module level is more Pythonic than trying to hide methods with name mangling.

查看更多
登录 后发表回答