下划线(_)是特殊的Python编写
虽然下划线(_)仅用于大多数语言中的蛇状变量和函数(当然,并非全部),但它在Python中有特殊含义。如果你是Python程序员,for _ in range(10) ,__init__(self)像语法可能很熟悉。
本文将解释何时以及如何使用下划线(_)并帮助您理解它。
在Python中使用下划线有5种情况。
1、用于存储解释器中最后一个表达式的值。
2、为了忽略具体的值。(所谓的“我不在乎”)
3、赋予特殊的含义和功能以指称易变的或功能的名称。
4、用作'国际化(i18n)'或'本地化(l10n)'功能。
5、分开数字字面值的数字。
我们来看看每个案例。
用于存储解释器中最后一个表达式的值
Python解释器将最后一个表达式值存储到名为'_'的特殊变量中。此功能首先在标准的CPython解释器中使用,您也可以在其他Python解释器中使用它。
>>> 10
10
>>> _
10
>>> _ * 3
30
>>> _ * 20
600
用于忽略这些值
该下划线也用于忽略特定值。如果您不需要特定值或者不使用这些值,只需将值分配给下划线。
# 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()
赋予变量和函数名称的特殊含义
该下划线可能是“命名”最常用的。作为Python约定指南的PEP8引入了以下4个命名案例。
_single_leading_underscore
该约定用于在模块中声明私有变量,函数,方法和类。任何有这种惯例的东西都会被忽略from module import *。
但是,Python不支持真正的私有属性,所以我们不能强制私有属性,也可以直接从其他模块中调用它。所以有时候我们会说它是“内部弱用指标”。
_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()
single_trailing_underscore_
这个约定可以用来避免与Python关键字或内建的冲突。你可能不会经常使用它。
Tkinter.Toplevel(master, class_='ClassName') # Avoid conflict with 'class' keyword
list_ = List.objects.get(1) # Avoid conflict with 'list' built-in type
__double_leading_underscore
这是关于语法而不是约定。双下划线将 破坏类的属性名称以避免类之间的属性名称冲突。(所谓的“mangling”,这意味着编译器或解释
器用一些规则修改变量或函数名称,而不是按照原样使用) Python的mangling规则是将“_ClassName”添加到属性名称的前面用double
声明下划线。 也就是说,如果您在类中编写名为“__method”的方法,则名称将以“_ClassName__method”格式变形。
class A:
def _single_method(self):
pass
def __double_method(self): # for mangling
pass
class B(A):
def __double_method(self): # for mangling
pass
由于使用双下划线命名的属性会像上面那样受到损坏,所以我们无法使用“ClassName .__ method”访问它。有时候,有些人会像使用这些功能的真正的私人用户一样使用它,但它不是私人的,也不是为此而推荐的。有关更多详细信息,请阅读Python命名。
__double_leading_and_trailing_underscore__
该约定用于特殊变量或方法(所谓的“魔术方法”),例如__init__,__len__。这些方法提供了特殊的语法功能或做特殊的事情。例如,__file__指示Python文件的位置,__eq__在执行a == b表达式时执行。
用户当然可以定制特殊的方法,这是非常罕见的情况,但往往可能会修改一些内置的特殊方法。(例如,你应该初始化这个类,__init__这个类将在一个类的实例被创建时首先执行。)
class A:
def __init__(self, a): # use special method '__init__' for initializing
self.a = a
def __custom__(self): # custom special method. you might almost do not use it
pass
随着国际化(i18n)/本地化(l10n)的发挥
这只是约定,没有任何语法功能。也就是说,下划线并不意味着i18n / l10n,它只是一个将i18n / l10n绑定到下划线变量的约定来自C约定。
内置的库gettext这是国际化/本地化采用了这种约定,并且Django的是Python的Web框架支持国际化/本地化还引入和采用了这种约定。
# 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.'))
分开数字字面值的数字
该功能是在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
结论
到目前为止,我们已经介绍了Python 的下划线。虽然我是一名Python程序员,但在写这篇文章之前,我并不了解他们中的一些东西。尤其是,i18n / l10n对我来说是非常新的。
和我一样,我希望你能从这篇文章中获得关于下划线的一些有用的知识。
接下来,我将介绍更多关于Python的有趣内容。谢谢。