Python中的下划线详解


Posted in Python onJune 24, 2015

这篇文章讨论Python中下划线_的使用。跟Python中很多用法类似,下划线_的不同用法绝大部分(不全是)都是一种惯例约定。

一、 单个下划线直接做变量名(_)

主要有三种情况:

1. 解释器中

_符号是指交互解释器中最后一次执行语句的返回结果。这种用法最初出现在CPython解释器中,其他解释器后来也都跟进了。

>>> _

Traceback (most recent call last):

  File "", line 1, in 

NameError: name '_' is not defined

>>> 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翻译查询函数,就应该避免再用作被丢弃的变量名。

二、 单下划线前缀的名称(例如_shahriar)
以单下划线做前缀的名称指定了这个名称是“私有的”。在 有些 导入import * 的场景中,下一个使用你代码的人(或者你本人)会明白这个名称仅内部使用。Python documentation里面写道:

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.

之所以说在在 有些 import * 的场景,是因为导入时解释器确实对单下划线开头的名称做了处理。如果你这么写from <module/package> import *,任何以单下划线开头的名称都不会被导入,除非模块/包的__all__列表明确包含了这些名称。更多相关信息见““Importing * in Python”。

三、双下划线前缀的名称(例如__shahriar)

以双下划线做前缀的名称(特别是方法名)并不是一种惯例;它对解释器有特定含义。Python会改写这些名称,以免与子类中定义的名称产生冲突。Python documentation中提到,任何__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被改写成了_ClassName__method_name。现在创建一个A的子类B(这可不是个好名字),就不会轻易的覆盖掉A中的__method_name了:

>>> class C(object):

...     def __mine__(self):

...         pass

...

>>> dir(C)

... [..., '__mine__', ...]

还是不要这样写方法名,只让Python定义的特殊方法名使用这种惯例吧。
Python 相关文章推荐
MySQLdb ImportError: libmysqlclient.so.18解决方法
Aug 21 Python
Python实现多线程HTTP下载器示例
Feb 11 Python
Python实现随机选择元素功能
Sep 14 Python
python2.7安装图文教程
Mar 13 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
Aug 02 Python
在Python中使用filter去除列表中值为假及空字符串的例子
Nov 18 Python
Python sep参数使用方法详解
Feb 12 Python
python使用pandas抽样训练数据中某个类别实例
Feb 28 Python
Python读取yaml文件的详细教程
Jul 21 Python
python 如何区分return和yield
Sep 22 Python
Django-Scrapy生成后端json接口的方法示例
Oct 06 Python
python中函数返回多个结果的实例方法
Dec 16 Python
Python装饰器使用实例:验证参数合法性
Jun 24 #Python
Python线程详解
Jun 24 #Python
Python函数式编程指南(四):生成器详解
Jun 24 #Python
Python函数式编程指南(三):迭代器详解
Jun 24 #Python
Python函数式编程指南(二):从函数开始
Jun 24 #Python
Python函数式编程指南(一):函数式编程概述
Jun 24 #Python
web.py在SAE中的Session问题解决方法(使用mysql存储)
Jun 24 #Python
You might like
PHP中几个常用的魔术常量
2012/02/23 PHP
php压缩HTML函数轻松实现压缩html/js/Css及注意事项
2013/01/27 PHP
深入Apache与Nginx的优缺点比较详解
2013/06/17 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
php编程中echo用逗号和用点号连接的区别
2016/03/26 PHP
PHP通过加锁实现并发情况下抢码功能
2016/08/10 PHP
PHP实现一个轻量级容器的方法
2019/01/28 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
JavaScript中的方法调用详细介绍
2014/12/30 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
2015/11/07 Javascript
jQuery插件jquery-barcode实现条码打印的方法
2015/11/25 Javascript
vue.js实现表格合并示例代码
2016/11/30 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
2017/03/03 Javascript
bootstrap时间控件daterangepicker使用方法及各种小bug修复
2017/10/25 Javascript
JavaScript实现一个带AI的井字棋游戏源码
2018/05/21 Javascript
vue.js template模板的使用(仿饿了么布局)
2018/08/13 Javascript
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
2018/11/01 NodeJs
vue中tab选项卡的实现思路
2018/11/25 Javascript
详解mpvue实现对苹果X安全区域的适配
2019/07/31 Javascript
解决ant Design Search无法输入内容的问题
2020/10/29 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
python实现全盘扫描搜索功能的方法
2019/02/14 Python
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
python3.7 sys模块的具体使用
2019/07/22 Python
Python Django 封装分页成通用的模块详解
2019/08/21 Python
python字典setdefault方法和get方法使用实例
2019/12/25 Python
Tensorflow tf.nn.atrous_conv2d如何实现空洞卷积的
2020/04/20 Python
详解如何将 Canvas 绘制过程转为视频
2021/01/25 HTML / CSS
如何手工释放资源
2013/12/15 面试题
退休感言
2014/01/28 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
golang 如何通过反射创建新对象
2021/04/28 Golang
Python实现学生管理系统(面向对象版)
2021/06/24 Python
Kubernetes控制节点的部署
2022/04/01 Servers