• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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 "", line 1, in <module>
    AttributeError: 'A' object has no attribute '__private'
    >>>a.__private_method() # 直接调用,不可见
    Traceback (most recent call last):
      File "", line 1, in <module>
    AttributeError: 'A' object has no attribute '__private_method'
    >>>a._A__private # 改为编译器改写后的真实属性名后,可见
    0
    >>>a._A__private_method() # 改为编译器改写后的真实方法名后,可见
    AAAAA
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    不过,在《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

  • 相关阅读:
    1186. 删除一次得到子数组最大和;1711. 大餐计数;1834. 单线程 CPU
    2 Elment Ui 日期选择器 格式化问题
    yolo增加MPDIoU loss
    day31
    python方法
    这个开源项目超哇塞,手写照片在线生成
    CUE语言基础入门:CUE是一门为配置而生的语言
    C#上位机与PLC
    QPair的介绍及用法
    论文技巧2
  • 原文地址:https://blog.csdn.net/bluishglc/article/details/128120395