Python笔记 · 私有方法私有属性 & 单下划线双下划线
Posted bluishglc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python笔记 · 私有方法私有属性 & 单下划线双下划线相关的知识,希望对你有一定的参考价值。
首先,不同于其他编程语言,Python中不存在真正意义上的“私有方法/属性”,Python中所胃的“私有方法”要么基于约定,要么基于编译期的改写(Name Mangling)。与私有方法、私有属性密切相关的是单下划线、双下划线。下面详细解释一下:
1. _*
以前置单下划线开始的方法名或属性名,这仅仅是一种形式上约定的私有方法或属性,在语法上无人任何约束性,人们仅仅是通过这种命名规范告知读者:这个方法或属性在定位上是私有的,不应在对像以外的地方使用。所以实际上,如果你想,还是可以在对像以外的地方调用或读写它们。以下是一段测试代码,用于验证该类方法或属性的可见性:
class A(object):
def __init__(self):
self._private=0
def _private_method(self):
print('AAAAA')
>>>a=A()
>>>a._private #可直接访问
0
>>>a._private_method() #可直接访问
AAAAA
2. __*
以前置双下划线开始的方法名或属性名,仍旧是用于标识私有方法或属性的,但较之于_*
有了一些“实质性的”变化,那就是你确实无法“直接”在对像以外的地方调用或读写它们了,这是因为:Python使用了Name Mangling技术,在编译时将__membername
改写成了 _classname__membername
,即:以双下划线开始的方法或属性都被"转义"成为单下划线+类名+双下划线+成员名的形式。所以,在知晓了转换规则后,你依然可以在对象外部以转义后的名称调用或读写它们。以下是一段测试代码,用于验证该类方法或属性的可见性:
class A(object):
def __init__(self):
self.__private=0
def __private_method(self):
print('AAAAA')
>>>a=A()
>>>a.__private # 直接调用,不可见
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'A' object has no attribute '__private'
>>>a.__private_method() # 直接调用,不可见
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'A' object has no attribute '__private_method'
>>>a._A__private # 改为编译器改写后的真实属性名后,可见
0
>>>a._A__private_method() # 改为编译器改写后的真实方法名后,可见
AAAAA
不过,在《Fluent Python》一书中,作者引用Ian Bicking 的一句话用于表达对__*
即Name Mangling的态度:
绝对不要使用两个前导下划线,这是很烦人的自私行为。如果担心名称冲突,应该明确使用一种名称改写方式(如
_MyThing_blahblah)。这其实与使用双下划线一样,不过自己定的规则比双下划线易于理解。
即:慎用最好不用__*
形式的私有方法或属性,这不是个好习惯。
3. __*__
以前置双下划线开始,后置双下划线结束的方法名,这已经和私有方法或属性无关了,这是Python语言系统定义的一些特殊函数,称之为:魔法函数 / Magic Methods / Dunder Methods, 我们将在另外一篇文章中单独介绍。
参考:
https://blog.csdn.net/sxingming/article/details/52875125
https://segmentfault.com/a/1190000040064040
以上是关于Python笔记 · 私有方法私有属性 & 单下划线双下划线的主要内容,如果未能解决你的问题,请参考以下文章
28.Python面向对象类:创建类&实例对象,私有属性,类里面的方法,类属性CRUD,常用内置类属性
28.Python面向对象类:创建类&实例对象,私有属性,类里面的方法,类属性CRUD,常用内置类属性