Python 'hide' methods with __

匿名 (未验证) 提交于 2019-12-03 01:39:01

问题:

Today I see that - python add _$CLASSNAME$ to methods with name with __.

Simple example:

>>> class A:   ...     def a(self):   ...         self.b()   ...     def b(self):   ...         print('A.b')   ...            >>> class B(A):   ...     def b(self):   ...         print('B.b')   ...            >>> B().a()   B.b 

That work, but:

>>> class A:   ...     def a(self):   ...         self.__b()   ...     def __b(self):   ...         print('A.b')   ...            >>> class B(A):   ...     def __b(self):   ...         print('B.b')   ...            >>> B().a()   A.b 

Why? I don't know, so I dir'ed it. Here it is:

>>> print([fn for fn in dir(B) if fn[-2:] != '__']) ['_A__b', '_B__b', 'a'] 

Why python do that? Is there way to bypass that?

回答1:

It's called name mangling and done to prevent accidental name collisions with parent and child classes. You cannot (and should not, a lot of perfectly fine code uses it) disable it. You can circumvent it, but you should not do that either (it's extremely ugly, you can avoid it, and when you need access to it you shouldn't permit name mangling in the first place). Just use a single underscore for private functions you want to use anywhere but immediately inside the class.

See the tutorial but ignore any reference to this denoting a "private" variable. That's not what it's used for unless you use private in the C++/Java/C#/... sense of private variables (as opposed to protected which are visible to child classes) being hidden from child classes. Even then it's a flawed analogy.



回答2:

While none of this is strictly enforced by python, the naming convention of a double underscore means "private", while a single underscore means "protected".

A double underscore is meant to protect subclasses from causing errors by using the same name. By namespacing them by class name, the defining class can be sure its variables will remain valid.

A single underscore means that subclasses are free to access and modify those same attributes, being shared with the super class.

Both forms suggest that any outside class should not be accessing these.

class A(object):      __private = 'private'     _protected = 'protected'      def show(self):         print self.__private          print self._protected  class B(A):     __private = 'private 2'     _protected = 'protected 2'  a = A() a.show() #private #protected  b = B() b.show() #private #protected 2 

This example shows that even though class B defined a new __private, it does not affect the inherited show method, which still accesses the original superclass attribute. _protected is however modified and the superclass show method reflects this, because they are the same attribute.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!