Python 中奇妙的下划线

单个下划线(_)

通常有三种用法:
  1. 在python解释器: 单个下划线代表上次在交互解释期对话中(控制台)执行的结果.这种情况在标准的CPython解释器中首次被实现,接下来这种习惯也被保持下来:
>>> _
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name ‘_‘ is not defined
>>> 42
>>> _
42
>>> ‘alright!‘ if _ else ‘:(‘
‘alright!‘
>>> _
‘alright!‘

2.作为一个名称:这可能跟上一点有点相关。单个下划线被当作‘被抛弃‘的名称来使用。这样可能另下一个阅读你代码的人知道,根据惯例,下划线代表这只声明但不会被使用的变量。正如,你不会对计数循环的变量有兴趣:

n = 42
for _ in range(n):
    do_something()

3.I18n: 有时候也会遇到单个下划线声明为一个函数的情况。在这种情况下,这个函数通常是用作国际化以及本地化的字符转化以及查找。这习惯似乎是来源并仍会继续跟随对应的C语言的习惯。举个例子,正如在Django documentation for translation里面,你可以看到:

from django.utils.translation import ugettext as _
from django.http import HttpResponse  

def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

在第二和第三两种用法有冲突,所以,应该避免同时用下划线作为‘被抛弃‘的变量以及i18n查找和转化

在名称前加单个下划线(例如 _name)

在名称前加单个下划线,这样可以用来告诉程序员,这个变量是私有变量。这是一种惯例,来让下一个人(或者你自己)使用代码的时候,知道这个下划线变量只是用于内部调用的。正如Python 文档记录着:

a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

我说明这种惯例是因为,在解释器中,它代表着某些特定用法。如果你 from <module/package> import *,除非 module‘s/package‘s  __all__文件明确的列出那些带单个下划线前缀的变量,否则所以这些变量都不会被导入。更多请参阅 "importing `*` from Python"

在名称前加两个下划线(例如 __name)

在名称面前添加两个下划线(特别是一个函数的名字)并不是一种惯例。对于解释器来说这是一种特殊的意义。Python会mangles(特性名词,不翻译,或者可以说让....失踪的意思)这些变量,从而避免子类定义的变量跟基类的冲突。正如 python文档有讲明,但凡这种形式的变量 __spam(至少两个前缀下划线,最多一个后缀下划线)都会被替换成 _classname__spam, 而在当前类 classname里面前缀的下划线都是被截取掉的。

可以看下面的例子:

>>> class A(object):
...     def _internal_use(self):
...         pass
...     def __method_name(self):
...         pass
...
>>> dir(A())
[‘_A__method_name‘, ..., ‘_internal_use‘]

正如所说的,_internal_use 没有改变而 __method_name 被mangled到 _Classname__method_name.现在,如果你想声明一个A的子类, B,然后你要想重写A的__method_name也不是那么容易的:

>>>> class B(A):
...     def __method_name(self):
...         pass
...
>>> dir(B())
[‘_A__method_name‘, ‘_B__method_name‘, ..., ‘_internal_use‘]

这种内定的特性,等同于Java 的final方法以及C++的普通方法(非虚函数)


名称前后都带有两个下划线(例如 __init__)

在Python里这代表这特殊方法。就我个人而言,这仅仅是一个惯例,可以让Python系统使用变量时,不会跟用户定义的变量冲突的一种方法。当Python 调用它们的时候,你可以典型的覆盖这些方法然后定义设定的行为。举个例子,你们在声明一个类的时候,都经常覆盖__init__方法。

没有人阻止你写你自己看起来像特殊方法的变量(但是,最好不要啦):

>>>> class C(object):
...     def __mine__(self):
...         pass
...
>>> dir(C)
... [..., ‘__mine__‘, ...]

要远离这种类型的变量声明很容易,只要让Python自定义的特殊变量声明自己去遵循这种惯例就好。

原文地址:https://www.cnblogs.com/yifdu25/p/8214046.html

时间: 2024-12-18 05:22:20

Python 中奇妙的下划线的相关文章

python中的单下划线和双下划线意义和作用

Python中并没有真正意义上的“私有”,类的属性的的可见性取决于属性的名字(这里的属性包括了函数).例如,以单下划线开头的属性(例如_spam),应被当成API中非公有的部分(但是注意,它们仍然可以被访问),一般是具体实现细节的部分.单下划线常用来实现模块级私有化,当我们使用“from mymodule import *”来加载模块的时候,不会加载以单下划线开头的模块属性. 而以双下划线开头并最多以一个下划线结尾的属性(例如___spam),将会被替换成_classname__spam这样的形

python中的单下划线,双下划线以及两端双下划线

1.在python的解释器中,_是上一条语句的执行结果,最早是CPython施行,到现在其他类型的解释器也在使用2.上面的语句执行结果是在屏幕上打印十行hello world,我们并不需要0-9这些数字,所以没必要给他一个变量名'_'3.单下划线:单下划线的变量是一种程序员之间美丽的约定——只要是这种变量就不要随便在类外部去访问它!!! 但是如果我们在导入模块时来看这个单下划线开头的变量,那就不一样了,在这里这种特殊名字的变量就变成了类似一种某个模块的“私有”变量,因为我们在使用from 模块名

Python 的类的下划线命名有什么不同?

1,以一个下划线开头的命名 ,如_getFile2,以两个下划线开头的命名 ,如__filename3,以两个下划线开头和结尾的命名,如 __init__()4,其它这些命名有什么不同吗 首先是单下划线开头,这个被常用于模块中,在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用 from a_module import * 导入时,这部分变量和函数不会被导入.不过值得注意的是,如果使用 import a_module 这样导入模块,仍然可以用 a_module._some_var

python&#160;里面的单下划线与双下划线的区别(私有和保护)

Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from module import *'导入 ——变量名_xxx被看作是“私有 的”,在模块或类外不可以使用.__xxx__ 系统定义名字 ——__xxx 类中的私有变量名 ——只有类对象自己能访问,连子类对象也不能访问到这个数据. 核心风格:避免用下划线作为变量名的开始. 因为下划线对解释器有特殊的意义,而且是内建标识符所使用的符号,我们建议程序员避免用下划线作为变量名的开始.一般来讲,变量名_xxx被看作是“私有 的

python 里面的单下划线与双下划线的区别

python 里面的单下划线与双下划线的区别 Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划线作为变量名的开始. 因为下划线对解释器有特殊的意义,而且是内建标识符所使用的符号,我们建议程序员避免用下 划线作为变量名的开始.一般来讲,变量名_xxx被看作是“私有 的”,在模块或类外不可以使用. 当变量是私有的时候,用_xxx 来表示变量是很好的习

python:类5——Python 的类的下划线命名有什么不同?

首先是单下划线开头,这个被常用于模块中,在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用 from a_module import * 导入时,这部分变量和函数不会被导入.不过值得注意的是,如果使用 import a_module 这样导入模块,仍然可以用 a_module._some_var 这样的形式访问到这样的对象. 在 Python 的官方推荐的代码样式中,还有一种单下划线结尾的样式,这在解析时并没有特别的含义,但通常用于和 Python 关键词区分开来,比如如果我们需

Python的类的下划线命名的区别

首先,单下划线开头,这个常被用于模块中,在一个模块中以单下划线开头的变量和函数被默认当做内部函数,如果使用from  module  import  *导入时,这部分变量和函数不会被导入.注意,如果使用import module导入模块,仍然可以用module._some_var这样的形式访问到这样的对象. 在Python官方推荐的代码样式中,还有一种单下划线结尾的样式,这在解析时并没有特别的含义,但通常用于和Python关键词区分开来,比如,如果我们需要一个变量叫做class,但class是P

oc将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接

/* 将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接(10分) 如传入:@"good_good_study_good_study" 返回:@"good_study" 如传入:@"I_love_I_hate_love_love" 返回:@"love_I_hate" */ 方法1:选择排序 -(NSString *)sortStringByNumbe

SQL搜索下划线,like中不能匹配下划线的问题

最近在检测天气预报15天查询网 站(http://tqybw.net)时的URL时,发现页面中有很些404页,分析发现,是请求地址的能参数中多了下划线“_”,而rewrite规 则中并没有配这样的规则,数据库表中出现“_”,并不多,想找出来把下划线去掉,按照正常的查找,结果返回记录不正常,找了下资料,原来下划线在like 中有着特殊的含义,它表示匹配任意一个字符.因此在查询包含下划线内容的时候需要“特殊关照”一下. 以下是分析及解决办法: 使用like语句的错误查询 mysql> select