Python-伪私有属性

时间:2023-11-10 23:20:56

原文:http://blog.itpub.net/26250550/viewspace-1411768/

通常在 Python 中,我们都被告知可以使用双下划线开头的方法名定义方法来达到私有函数的目标。
事实上,这个认识是错误的,这个方法更多的是一个强拼硬凑的惯用法。

首先,在 Python 中,就没有访问控制的概念,这不同于其他 OO 语言, Python 的哲学是假定使用者都会使用,不需要设计者规定访问权限,这和 Python 很多地方的设计思路是一致的,就是要简单,要相信大家都是会思考的人。

那么,双下划线又是什么呢?事实上 Python 中的以双下滑开头的类方法名,在类实例化以后会自动被概念,在其名字前加 _classname ,因为名字被改了,所以自然无法用双下滑开头的名字被访问,从而达到不可进入的目的。

其他的语言,比如JAVA,C++的oop语法都比较的规范,有公有,私有和保护的数据类型,而python的话,从我目前的观察来看,python的类 是没有权限控制的,所有变量都是可以被外部调用的,那你会说:"python明明有私有的定义方法就是在变量或者方法的面前加上双下滑线__,但是我告诉 你,这个实际上是python的伪私有。只是一种程序员约定俗称的规定,加了就表示私有变量,但是你如果要在外部调用的话,还是可以调用的。

私有变量:实例._类名__变量名
私有方法:实例._类名__方法名()
例如:

class Info:
def __init__(self):
self.__name = 'jay'
def __say(self):
print(self.__name) #访问方式:
a = Info()
print(a._Info__name) # 'jay'
print(a._Info__say()) # 'jay'
### 获取类的属性和方法
# 获取类的所有属性
>>>print(a.__dict__)
{'_Info__name': 'jay'} # 获取类的所有属性和方法
>>>print(dir(a))
['_Info__name', '_Info__say', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__h
ash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__re
duce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '_
_subclasshook__', '__weakref__']

私有属性、方法——Python并没有真正的私有化支持,但可用下划线得到伪私有
尽量避免定义以下划线开头的变量
   (1)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问;不能用'from module import *'导入
   (2)__xxx    类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。)," 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
    (3)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__() 代表类的构造函数。

__开头的本来就是表示private, private是不可继承的

python有私有的定义方法就是在变量或者方法的面前加上双下滑线__,但是实际上这是python的伪私有。只是一种程序员约定俗称的规定,加了就表示私有变量,但是如果要在外部调用的话,还是可以调用的,调用方法如下:
   所有以双下划线开始的变量,都被python翻译为前面加上单下划线和类名
如属性__inaccessible 翻译为 Secretive._Secretive__inaccessible,注意第一个为单下划线,第二个为双下划线:

>>>class Secretive:
def __inaccessible(self): #双下划线表示私有方法
print("Bet you can't see me...")
def accessible(self):
print("The secret message is:")
self.__inaccessible() >>> s = Secretive()
>>> s.__inaccessible() #私有方法从外界是无法访问的,报错
Traceback (most recent call last):
File "", line 1, in
s.__inaccessible() #私有方法从外界是无法访问的
AttributeError: Secretive instance has no attribute '__inaccessible'
>>>
>>>
>>> s.accessible() #私有方法只能在类内部使用
The secret message is:
Bet you can't see me...
>>>
>>>
>>> s._Secretive__inaccessible() #虽然私有,仍能调用,伪私有机制
Bet you can't see me...