• Python中的五种下划线


      1 1、单前导下划线 _var
      2 
      3 单个下划线是一个Python命名约定,表示这个名称是供内部使用的。 它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示
      4 
      5 程序员使用名称前的单下划线,用于指定该名称属性为“私有”。这有点类似于惯例,为了使其他人(或你自己)使用这些代码时将会知道以“_”开头的名称只供内部使用。正如Python文档中所述:
      6 以下划线“_”为前缀的名称(如_spam)应该被视为API中非公开的部分(不管是函数、方法还是数据成员)。此时,应该将它们看作是一种实现细节,在修改它们时无需对外部通知。
      7 正如上面所说,这确实类似一种惯例,因为它对解释器来说确实有一定的意义,如果你写了代码“from <模块/包名> import *”,那么以“_”开头的名称都不会被导入,除非模块或包中的“__all__”列表显式地包含了它们。
      8 
      9 class Test:
     10     def __init__(self):
     11         self.foo=11
     12         self._bar=23
     13 t=Test()
     14 print(t.foo)
     15 print(t._bar)
     16 
     17 _bar中的单个下划线并没有阻止我们“进入”类并访问该变量的值。这是因为Python中的单个下划线前缀仅仅是一个约定 - 至少相对于变量和方法名而言。但是,前导下划线的确会影响从模块中导入名称的方式。
     18 假设你在一个名为client.py的模块中有以下代码:
     19 
     20 def external_func():
     21     return 23
     22 def _internal_func():
     23     return 42
     24 
     25 如果使用通配符从模块中导入所有名称,则Python不会导入带有前导下划线的名称(除非模块定义了覆盖此行为的__all__列表):
     26 from client import *
     27 print(external_func())
     28 print(_internal_func())  #NameError: name '_internal_func' is not defined
     29 顺便说一下,应该避免通配符导入,因为它们使名称空间中存在哪些名称不清楚。 为了清楚起见,坚持常规导入更好。
     30 
     31 常规导入不受前导单个下划线命名约定的影响:
     32 import client
     33 print(client.external_func())
     34 print(client._internal_func())
     35 
     36 
     37 
     38 2、单末尾下划线 var_
     39 有时候,一个变量的最合适的名称已经被一个关键字所占用。 因此,像class或def这样的名称不能用作Python中的变量名称。 在这种情况下,你可以附加一个下划线来解决命名冲突:
     40 单个末尾下划线(后缀)是一个约定,用来避免与Python关键字产生命名冲突。 PEP 8解释了这个约定。
     41 def make_object(name,class):
     42     pass
     43 
     44 
     45 
     46 3、双前导下划线 __var
     47 名称(具体为一个方法名)前双下划线(__)的用法并不是一种惯例,对解释器来说它有特定的意义。Python中的这种用法是为了避免与子类定义的名称冲突。Python文档指出,“__spam”这种形式(至少两个前导下划线,最多一个后续下划线)的任何标识符将会被“_classname__spam”这种形式原文取代,在这里“classname”是去掉前导下划线的当前类名。
     48 
     49 class A(object):
     50     def _internal_use(self):
     51         pass
     52     def __method_name(self):
     53         pass
     54 print(dir(A()))
     55 
     56 # ['_A__method_name', '__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__', '_internal_use']
     57 
     58 正如所预料的,“_internal_use”并未改变,而“__method_name”却被变成了“_ClassName__method_name”。此时,如果你创建A的一个子类B,那么你将不能轻易地覆写A中的方法“__method_name”。
     59 
     60 class B(A):
     61     pass
     62 print(dir(B()))
     63 
     64 # ['_A__method_name', '__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__', '_internal_use']
     65 
     66 
     67 
     68 4、双前导和双末尾下划线 _var_
     69 也许令人惊讶的是,如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。 由双下划线前缀和后缀包围的变量不会被Python解释器修改:
     70 
     71 class PrefixPostfixTest:
     72     def __init__(self):
     73         self.__bam__=42
     74 print(PrefixPostfixTest().__bam__) # 42
     75 
     76 但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ --- 它使得一个对象可以被调用。
     77 这些dunder方法通常被称为神奇方法 - 但Python社区中的许多人都不喜欢这种方法。
     78 最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。
     79 
     80 
     81 
     82 
     83 1、在解释器中:在这种情况下,“_”代表交互式解释器会话中上一条执行的语句的结果。这种用法首先被标准CPython解释器采用,然后其他类型的解释器也先后采用。
     84  2、作为一个名称:这与上面一点稍微有些联系,此时“_”作为临时性的名称使用。这样,当其他人阅读你的代码时将会知道,你分配了一个特定的名称,但是并不会在后面再次用到该名称。例如,下面的例子中,你可能对循环计数中的实际值并不感兴趣,此时就可以使用“_”。
     85 n = 42
     86 for _ in range(n):
     87 do_something()
     88 3、国际化:也许你也曾看到”_“会被作为一个函数来使用。这种情况下,它通常用于实现国际化和本地化字符串之间翻译查找的函数名称,这似乎源自并遵循相应的C约定。
     89 
     90 可以发现,场景二和场景三中的使用方法可能会相互冲突,所以我们需要避免在使用“_”作为国际化查找转换功能的代码块中同时使用“_”作为临时名称。
     91 
     92 总结:
     93 Python下划线命名模式 - 小结
     94 以下是一个简短的小结,即“速查表”,罗列了本文中谈到的五种Python下划线模式的含义:
     95 
     96 
     97 
     98 转载自:《不知道这5种下划线的含义,你就不算真的会Python!》
     99 subtitle
    100 51Testing软件测试网
    101 03-07 17:35
  • 相关阅读:
    简单的统计指定进程ID(或进程名)CPU、内存脚本
    如何快速破解关注微信公众号才能阅读全文的技术文章 All In One
    2022 软考 All In One
    无任何框架依赖的纯原生 HTML CSS JS 练习项目 All In One
    TypeScript Type Aliases vs Interfaces All In One
    python 中创建函数及传递参数
    python 统计fasta文件每条scalfold的碱基长度
    linux 中 shasum命令
    ubuntu 中如何创建root用户
    ubuntu 中 设置putty登录
  • 原文地址:https://www.cnblogs.com/zpdbkshangshanluoshuo/p/10503650.html
Copyright © 2020-2023  润新知