做者:mingrammerhtml
翻譯:老齊python
與本文相關的圖書推薦:《跟老齊學Python:輕鬆入門》程序員
下劃線(_
)在Python語言中有特殊做用。web
在大多數編程語言中,下劃線是命名變量或者函數名稱時的連字符,可是,在Python語言中,不只如此。若是你是一名Python程序員,對於諸如 _ in range(10)
, __init__(self)
之類的下發確定熟知。編程
本文將詳述下劃線(_
)的使用方法,幫助初學者理解它。bash
在Python語言中,下劃線主要應用在以下5個方面:app
下面逐一闡述。框架
在Python交互模式總,若是調用_
,會顯示最近的表達式的值。這個功能在標準的交互模式中都有,你也能夠在其它Python交互式解析器中使用。dom
>>> 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中命名方式。
以單下劃線開始的變量、函數、方法、類名稱,意在聲明該對象私有化,按照此預訂,使用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()
複製代碼
爲了不與Python關鍵詞和其餘內置對象名稱衝突,經常用這種命名方式,你能夠不用它。
Tkinter.Toplevel(master, class_='ClassName') # Avoid conflict with 'class' keyword
list_ = List.objects.get(1) # Avoid conflict with 'list' built-in type
複製代碼
這個超越通常約定的語法。當程序運行的時候,Python解析器會對以雙下劃開始的類中的屬性、方法名稱重命名,從而避免不一樣的類中一樣名稱之間的衝突,基本規則是在雙下劃線開始的名稱前面增長形如「_ClassName」樣式的前綴。
例如在類中有名爲__method
的方法,這個名字會被改名爲_ClassName__method
形式。
class A:
def _single_method(self):
pass
def __double_method(self): # for mangling
passclass B(A):
def __double_method(self): # for mangling
pass
複製代碼
如上面所述,以雙下劃線爲開始命名的屬性和方法,咱們不能用ClassName.__method
方式調用,所以,有人把這做爲真正的私有化,可是,這裏不推薦這種私有化方式,依據就是Python的命名規則。
譯者注: 此處做者的觀點,僅供參考。_namne
這種方式私有化,是約定的私有化,不是真正的私有化;__name
這種方式真正實現了「私有化」,但在編程中是否採用,有不一樣的觀點。或者說對於「私有化」,在Python中是有不一樣理解的。
這種約定用於特殊的變量或者方法——稱爲「魔法方法」(譯者想:「magic method」,是否是翻譯成「魔幻方法」更好呢?這些特殊方法原本就讓學習者感到很「魔幻」。),好比__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),僅僅是由於這種習慣來自C語言中的習慣。
內置標準庫的模塊gettext,能夠用於演示i18n/l10n。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.'))
複製代碼
這個功能是在Python3.6中加入的,用下劃線做爲數字的分隔符。
dec_base = 1_000_000
bin_base = 0b_1111_0000
hex_base = 0x_1234_abcdprint(dec_base) # 1000000
print(bin_base) # 240
print(hex_base) # 305441741
複製代碼
本文總結了Python中下換線的使用方法,有的方法或許對你是比較新鮮的,好比i18n/l10n,此前我就不知道。但願本文能對你有啓發。
搜索技術問答的公衆號:老齊教室
在公衆號中回覆:老齊,可查看全部文章、書籍、課程。