首页 > 代码库 > 伪私有属性的意义

伪私有属性的意义

  抛开语言层面,在通常的面向对象编程中(典型的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]

 总结

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

伪私有属性的意义