
前言
原文傳送門:閱讀原文
作者: mingrammer
編譯:HuangweiAI
在Python中,下劃線(_)是特殊的。如果您是python程式員,對于
for _ in range(10)
,以及
__init__(self)
的文法可能比較熟悉。
這篇文章将解釋什麼時候以及如何使用下劃線(_),并幫助你了解它。
在Python中有5種使用下劃線的情況:
- 用于在解釋器中存儲最後一個表達式的值。
- 忽略特定的值。
- 給變量名或函數名賦予特殊的意義和功能。
- 用作“國際化(i18n)”或“本地化(l10n)”。
- 将數字的值分開。

在解釋器中使用時
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()
複制

賦予變量和函數名稱特殊的含義
下劃線可能最常用于“命名”。PEP8是Python的約定準則,它介紹了以下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 (首部雙下劃線)
這是文法而不是約定的。雙下劃線将”矯正“類的屬性名,以避免類之間的屬性名沖突。(所謂的“矯正”是指編譯器或解釋器用一些規則修改變量或函數名,而不是按原樣使用)
Python的矯正規則是在屬性名前面加上雙下劃線聲明“_ClassName”。也就是說,如果你在一個類中編寫了一個名為“__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”通路它。有時,有些人使用它就像真正的私人使用這些功能,但它不是私人的,也不推薦這樣做。
__double_leading_and_trailing_underscore__ (首尾部雙下劃線)
這個約定用于特殊的變量或方法(所謂的“魔法方法”),如:__init__, __len__。這些方法提供了特殊的文法特征或做了特殊的事情。例如,__file__表示Python檔案的位置,當a==b表達式被執行時,__eq__被執行。
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語言約定。用于i18n/l10n的内置庫gettext使用了這種約定,Python web架構Django支援i18n/l10n也引入并使用了這種約定。
# 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
複制
·END·