下劃線(_)是特殊的Python編寫
雖然下劃線(_)僅用于大多數(shù)語言中的蛇狀變量和函數(shù)(當然,并非全部),但它在Python中有特殊含義。如果你是Python程序員获雕,for _ in range(10) ,__init__(self)像語法可能很熟悉轿偎。
本文將解釋何時以及如何使用下劃線(_)并幫助您理解它典鸡。
在Python中使用下劃線有5種情況。
1坏晦、用于存儲解釋器中最后一個表達式的值萝玷。
2、為了忽略具體的值昆婿。(所謂的“我不在乎”)
3球碉、賦予特殊的含義和功能以指稱易變的或功能的名稱。
4仓蛆、用作'國際化(i18n)'或'本地化(l10n)'功能睁冬。
5、分開數(shù)字字面值的數(shù)字。
我們來看看每個案例豆拨。
用于存儲解釋器中最后一個表達式的值
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()
賦予變量和函數(shù)名稱的特殊含義
該下劃線可能是“命名”最常用的邮绿。作為Python約定指南的PEP8引入了以下4個命名案例。
_single_leading_underscore
該約定用于在模塊中聲明私有變量攀例,函數(shù)船逮,方法和類。任何有這種慣例的東西都會被忽略from module import *粤铭。
但是挖胃,Python不支持真正的私有屬性,所以我們不能強制私有屬性承耿,也可以直接從其他模塊中調(diào)用它冠骄。所以有時候我們會說它是“內(nèi)部弱用指標”伪煤。
_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關鍵字或內(nèi)建的沖突加袋。你可能不會經(jīng)常使用它。
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”,這意味著編譯器或解釋
器用一些規(guī)則修改變量或函數(shù)名稱防泵,而不是按照原樣使用) Python的mangling規(guī)則是將“_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__在執(zhí)行a == b表達式時執(zhí)行绪撵。
用戶當然可以定制特殊的方法呐馆,這是非常罕見的情況,但往往可能會修改一些內(nèi)置的特殊方法莲兢。(例如汹来,你應該初始化這個類,__init__這個類將在一個類的實例被創(chuàng)建時首先執(zhí)行改艇。)
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)的發(fā)揮
這只是約定收班,沒有任何語法功能。也就是說谒兄,下劃線并不意味著i18n / l10n摔桦,它只是一個將i18n / l10n綁定到下劃線變量的約定來自C約定。
內(nèi)置的庫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.'))
分開數(shù)字字面值的數(shù)字
該功能是在Python 3.6中添加的。它用于使用下劃線來分隔數(shù)字的數(shù)字以提高可讀性燕鸽。
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
結(jié)論
到目前為止兄世,我們已經(jīng)介紹了Python 的下劃線。雖然我是一名Python程序員啊研,但在寫這篇文章之前御滩,我并不了解他們中的一些東西。尤其是党远,i18n / l10n對我來說是非常新的削解。
和我一樣,我希望你能從這篇文章中獲得關于下劃線的一些有用的知識沟娱。
接下來氛驮,我將介紹更多關于Python的有趣內(nèi)容。謝謝济似。