zoukankan      html  css  js  c++  java
  • python-神奇的下划线

    2019-12-16 22:45:29

    python中下划线有各种各样的作用,本章就来分别介绍一下各种下划线的功能。

    一、开头单下划线 _VAR

    开头单下划线还是挺常用的,在类中表示为保护变量/保护函数,但是需要注意的是,这个只是一种约定俗成,这不是Python强制规定的。

    换言之,你依然可以访问一个类中以单下划线开头的变量或者方法而不报错。

    class a:
        def __init__(self):
            self.a = 1
            self._b = 2
    
        def _func(self):
            print("Hello world.")
            
    
    if __name__ == "__main__":
        aa = a()
        print(aa.a)
        print(aa._b)
        aa._func()

    上述的代码运行是完全没有任何的问题的,这是因为Python中的单个下划线前缀仅仅是一个约定 - 至少相对于变量和方法名而言。

    但是,前导下划线的确会影响从模块中导入名称的方式。

    假设你在一个名为my_module的模块中有以下代码:

    # This is my_module.py:
    
    def external_func():
       return 23
    
    def _internal_func():
       return 42
    

    现在,如果使用通配符从模块中导入所有名称,则Python不会导入带有前导下划线的名称:

    >>> from my_module import *
    >>> external_func()
    23
    >>> _internal_func()
    NameError: "name '_internal_func' is not defined"

    当然,如果不是使用通配符进行的导入,那么依然是不会出现任何的问题的,事实上,我们也不建议使用通配符的方式来进行方法的导入。

    二、开头双下划线 __VAR

    上述的单下划线开头有点类似于君子协定,看到了就是告诉你这个是私有的,不能外部访问的,但是实际上你要外部访问也没辙。但是,开头双下划线的就不一样了,这个在python中有固定的使用方式的。

    双下划线前缀会导致Python解释器重写属性名称,以避免子类中的命名冲突。

    python会对以双下划线开头的变量或者方法的name进行重写(_ClassName__VAR),在外部访问的时候如果直接按照变量名访问就会报错。

    class Test:
        def __init__(self):
           self.foo = 11
           self._bar = 23
           self.__baz = 23
    
        def get_var(self):
            print(self.__baz) # 内部可以直接访问
        
        def __method(self):
            print("This is method.")
    
    
    if __name__ == "__main__":
        a = Test()
    
        # print(a.__baz) # AttributeError: 'Test' object has no attribute '__baz'
        print(a._Test__baz)
    
        # 对内透明
        a.get_var()
    
        # a.__method() # AttributeError: 'Test' object has no attribute '__method'
        a._Test__method()
    

      

    三、开头末尾双下划线

    如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。 由双下划线前缀和后缀包围的变量不会被Python解释器修改:

    class PrefixPostfixTest:
       def __init__(self):
           self.__bam__ = 42
    
    >>> PrefixPostfixTest().__bam__
    42
    

    但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ --- 它使得一个对象可以被调用。

    这些dunder方法通常被称为神奇方法 - 但Python社区中的许多人(包括我自己)都不喜欢这种方法。

    最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。

  • 相关阅读:
    《机器学习》第二次作业——第四章学习记录和心得
    机器学习一到三章笔记
    [ML] 第四章学习总结
    [CV] Mnist手写数字分类
    ModelArts (华为GPU/CPU计算云平台)体验
    [DataSturcture] 红黑树求逆序对
    [CV] 边缘提取和角点判断
    [CV] 灰度共生矩阵
    [DataStructure] AC 自动机(Aho–Corasick Automata)
    [GIT] 如何删除git上保存的文件(包含历史文件)
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12052107.html
Copyright © 2011-2022 走看看