伪私有属性的意义

  抛开语言层面,在通常的面向对象编程中(典型的C++),类都有私有属性。这是为了封装自己的属性,并且保证不会被外界调用修改而只能自己的方法调用修改。由于动态语言的特性,python中不存在严格封装特性,可以在外界随意调用类中任何属性和方法。一般我们想在类中申明一些不想被外界调用的私有属性时,通常约定俗成地会在属性名字的前面加上单下划线,如class._status.如果在使用别人写好的代码中看到了加了下划线的属性时,其实应该清楚最好不要调用甚至是修改它。

  在其它代码中有时还会看到属性名字的前面加上了双下划线,如果还想通过双下划线调用属性时就会报错,说没有这个属性。注意,这和单下划线不同。在类的作用域中,当解释器遇到以双下划线开头的属性时,会在双下划线前面加上类的名字。这样做的目的就很明确了,就是强制要求这个属性被外界调用,而且连继承它的类的实例也不能使用。说白了,连继承都不行。

class C1():
    def meth1(self):
        self.__x = 'Hello World'
    def meth2(self):
        print(self.__x)

class C2():
    def meth3(self):
        self.__o__x = 'Hello Python'
    def meth4(self):
        print(self.__o__x)

class C3(C1, C2):
    pass

c3 = C3()
c3.meth1()
c3.meth3()
c3.meth2()
c3.meth4()

输出为:

Hello World
Hello Python

再调用c3的__x:

c3.__x   # 如下所示,这个对象中没有__x这个属性

输出为:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-777a67f96b15> in <module>()
----> 1 c3.__x   # 如下所示,这个对象中没有__x这个属性

AttributeError: 'C3' object has no attribute '__x'

再执行:

print(dir(c3))   # 在下面中,注意看__x属性

输出为:

['_C1__x', '_C2__o__x', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', 

'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 

'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 

'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 、

'__weakref__', 'meth1', 'meth2', 'meth3', 'meth4']

 总结

  在类中,加单下划线的属性可以被外界调用,但不推荐;加双下划线的属性更不能被外界调用,甚至继承它的类都不行。如果实在想调用,可以在双下划线前面加上_类的名字。这样就更不推荐,自己心里明白就行。

原文地址:https://www.cnblogs.com/zhouyang123200/p/6538226.html