使用__的Python"隐藏"方法

Rad*_*nik 5 python oop inheritance

今天我看到 - python添加_$CLASSNAME$到名称为的方法__.

简单的例子:

>>> 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
Run Code Online (Sandbox Code Playgroud)

那项工作,但是:

>>> 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
Run Code Online (Sandbox Code Playgroud)

为什么?我不知道,所以我给了它.这里是:

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

为什么python这样做?有办法绕过那个吗?

jdi*_*jdi 12

虽然这些都不是python严格执行的,但双下划线的命名约定意味着"私有",而单个下划线意味着"受保护".

双下划线旨在通过使用相同的名称来保护子类不会导致错误.通过按名称对它们进行命名,定义类可以确保其变量保持有效.

单个下划线意味着子类可以自由访问和修改那些与超类共享的相同属性.

两种形式都表明任何外部类都不应该访问这些.

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
Run Code Online (Sandbox Code Playgroud)

此示例显示即使类B定义了一个new __private,它也不会影响继承的show方法,该方法仍然访问原始的超类属性._protected然而,修改了超类show方法,因为它们是相同的属性.

  • 需要注意的是,`__private` 并不是真正的私有,你仍然可以通过 `i = B(); 访问和操作它;i._B__private`。我有一种方法可以使事情几乎真正私密(仍然可以访问`__closure__`):https://www.daniweb.com/programming/threads/510759/snippet-how-to-privatize-attributes-of-a-插槽类#post2229436 (2认同)

小智 9

它被称为名称修改,用于防止与父类和子类的意外名称冲突.你不能(也不应该,很多完美的代码使用它)禁用它.你可以规避它,但你不应该这样做(它非常难看,你可以避免它,当你需要访问它时,你不应该首先允许名称修改).只需使用单个下划线即可在任何地方使用私有函数,但只能在类中使用.

请参阅教程,但忽略对此的任何引用,表示"私有"变量.这不是它的用途,除非你private在C++/Java/C#/ ... 中使用隐含在子类中的private变量(protected与子类可见相反).即使这样,它也是一个有缺陷的类比.