2017-06-26-python中神奇的下划线
Table of Contents
下划线 _
在python中有一些特殊地用法。我觉得 这篇文章 总结得很好了。
基本上我是把它翻译了一下。就算是做笔记了。下划线在python中的使用,可能
是一些约定,也可能是语法要求。主要分为下面5种。
There are 5 cases for using the underscore in Python.
- For storing the value of last expression in interpreter.
- For ignoring the specific values. (so-called “I don’t care”)
- To give special meanings and functions to name of vartiables or functions.
- To use as ‘Internationalization(i18n)’ or ‘Localization(l10n)’ functions.
- To separate the digits of number literal value.
1 存储解释器上一次执行的结果
>>> 10 10 >>> _ 10 >>> _ * 3 30 >>> _ * 20 600
2 忽略一些特殊的值
可能用户并不care这些特殊值或这些值就没有使用,就把它赋给下划线啦:
# Ignore a value when unpacking x, _, y = (1, 2, 3) # x = 1, y = 3 # Ignore the multiple values. It is called "Extended Unpacking" which # is available in only Python 3.x x, *_, y = (1, 2, 3, 4, 5) # x = 1, y = 5 # Ignore the index for _ in range(10): do_something() # Ignore a value of specific location for _, val in list_of_tuple: do_something() for root, _, files in os.walk(): do_something()
3 给变量或者函数以特殊地意义
3.1 以一个下划线开头
只是防止模块的属性用 from mymodule import *
来加载。对比上面的例
子:
如果 test.py
长这样:
_internal_name = 'one_nodule' # private variable _internal_version = '1.0' # private variable class _Base: # private class _hidden_factor = 2 # private variable def __init__(self, price): self._price = price def _double_price(self): # private method return self._price * self._hidden_factor def get_double_price(self): return self._double_price()
那在其他python文件中这样引用是使用不了的啦:
from test1 import * print _internal_name
但是可以显式地指定,所以python中的“私有”只是相对的:
from test1 import _internal_name print _internal_name
3.2 以一个下划线结尾
一般是避免和python中的内置名称冲突:
Tkinter.Toplevel(master, class_='ClassName') # Avoid conflict with 'class' keyword list_ = List.objects.get(1) # Avoid conflict with 'list' built-in type
3.3 以两个下划线开头
这是下划线为数不多地做为语法使用的情况:
该属性在运行时被混淆。如下代码:
#!/usr/local/bin/python class RandSeq(object): """Documentation for RandSeq """ def __init__(self, seq): super(RandSeq, self).__init__() self.__data = seq def __nonzero__(self): return False r = RandSeq(12) # print r.__data print r._RandSeq__data
直接访问 __data
是不行的。但是可以使用 _RandSeq__data
来访问。
也就是说以 __
开头的属性,不是不能访问了。而是在运行时在前面加上
了 _Classname
。这样父类子类的以 __
开头的属性在运行时看起来好
像就是自己“私有”的了。
3.4 以两个下划线开头和结尾
一般是一些特殊地(也称为“魔法函数”)的方法,比如 __init__(),
__len()
。它们提供特殊的写法,当然也做特殊的事情啦。一般不要重写它
们。
4 做为国际化、本地化的功能
比如 gettext
:
# see official docs : https://docs.python.org/3/library/gettext.html import gettext gettext.bindtextdomain('myapplication','/path/to/my/language/directory') gettext.textdomain('myapplication') _ = gettext.gettext # ... print(_('This is a translatable string.'))
5 分隔字面值的数字
注意 这是 python 3.6
的新功能。
dec_base = 1_000_000 bin_base = 0b_1111_0000 hex_base = 0x_1234_abcd print(dec_base) # 1000000 print(bin_base) # 240 print(hex_base) # 305441741