理解Python中的下劃線(_)的五種用法

2020-03-06     機器學習與數據分析

前言

在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

忽略特定的值

下劃線還用於忽略特定的值。如果不需要特定的值,或者不使用這些值,只需將這些值賦給下劃線即可。

下劃線還用於忽略特定的值。如果不需要特定的值,或者不使用這些值,只需將這些值賦給下劃線即可。

賦予變量和函數名稱特殊的含義

下劃線可能最常用於「命名」。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

參考

https://medium.com/hackernoon/understanding-the-underscore-of-python-309d1a029edc

文章來源: https://twgreatdaily.com/gwfDwXAB3uTiws8Kzzg1.html