哈嘍大家好,我是咸魚
當(dāng)我們在學(xué)習(xí) Python 的時(shí)候,可能會(huì)經(jīng)常遇到單下劃線 _
和雙下劃線 __
這兩種命名方式
單下劃線 _
和雙下劃線 __
不僅僅是只是一種簡單的命名習(xí)慣,它們在 Python 中有著特殊的含義,對于代碼的可讀性和功能實(shí)現(xiàn)有著關(guān)鍵的作用。
那么今天我們來看一看在 Python 中單下劃線和雙下劃線的用法和意義
前導(dǎo)單下劃線
前導(dǎo)單下劃線(Leading Single Underscore)通常用于命名變量、方法和屬性,表示這些命名的元素是【私有】的或者說是【內(nèi)部使用】的。
這種命名約定并不是嚴(yán)格的語言規(guī)則(即非強(qiáng)制性),而是一種約定,告訴開發(fā)人員該對象不應(yīng)該被外部直接訪問或修改
_internal_variable = 10
比如說下面的例子中,_internal_var
和_internal_method
都以前導(dǎo)單下劃線開頭,表示它們是類的內(nèi)部使用。
而public_method
是公共方法,可以在類外部訪問。
class MyClass:
def __init__(self):
self._internal_var = 42 # 前導(dǎo)單下劃線表示該變量是內(nèi)部使用的
def _internal_method(self):
return 'This is an internal method'
def public_method(self):
# 在公共方法中調(diào)用內(nèi)部方法和變量
print(self._internal_method())
print(f'The internal variable is: {self._internal_var}')
雖然可以在類外部訪問前導(dǎo)單下劃線命名的變量和方法,但是按照約定,建議只在類內(nèi)部使用,而避免在類外部直接訪問它們。
單下劃線
單下劃線通常用作一個(gè)占位符,用于表示一個(gè)不重要的變量名或迭代中的臨時(shí)變量,即在解構(gòu)賦值或循環(huán)迭代中不需要使用的變量
例子一中,_
用作一個(gè)占位符變量,表示在tuple_returning_function()
返回的元組中的某個(gè)值,但是在解構(gòu)賦值中沒有被使用。
def tuple_returning_function():
return (1,1), (2,2), (3,3)
_ , tuple_I_need, _ = tuple_returning_function()
例子二中,_
用作循環(huán)迭代中的占位符,因?yàn)檠h(huán)體中不需要使用循環(huán)變量的值,只是執(zhí)行了三次打印操作
for _ in range(0,3):
print("打印三次")
單尾隨下劃線
單個(gè)后綴下劃線(Single trailing underscores)通常用于避免與 Python 關(guān)鍵字產(chǎn)生命名沖突。它被用作標(biāo)識符的后綴,以示與Python關(guān)鍵字有所區(qū)別。
比如說我想使用一個(gè)在 Python 中已經(jīng)是保留關(guān)鍵字的變量名時(shí),比如class、def、type等。為了避免沖突,可以添加后綴下劃線
class_ = "Computer Science"
type_ = “字符串”
Dunder 方法
Dunder 方法指的是以雙下劃線(__
)開頭和結(jié)尾的特殊方法(也稱為魔術(shù)方法或特殊方法)。
這些方法具有特殊的行為,可以在自定義類中重寫以改變類的行為。Dunder方法的名稱是Python中預(yù)定義的,例如__init__
、__str__
、__repr__
等。
下面是一些常見的 Dunder 方法:
-
__init__(self, ...)
: 初始化方法,在對象實(shí)例化時(shí)調(diào)用,用于初始化對象的屬性。 -
__str__(self)
: 將對象轉(zhuǎn)換為字符串表示形式,當(dāng)使用print()
函數(shù)或str()
函數(shù)時(shí)調(diào)用。 -
__repr__(self)
: 返回一個(gè)包含對象信息的字符串,通常用于開發(fā)和調(diào)試,可通過repr()
函數(shù)調(diào)用。 -
__len__(self)
: 返回對象的長度,通過len()
函數(shù)調(diào)用。 -
__getitem__(self, key)
: 獲取對象的元素,用于索引操作,例如obj[key]
。 -
__setitem__(self, key, value)
: 設(shè)置對象的元素,用于索引賦值操作,例如obj[key] = value
。 -
__delitem__(self, key)
: 刪除對象的元素,用于索引刪除操作,例如del obj[key]
。 -
__call__(self, ...)
: 將對象作為函數(shù)調(diào)用,使得對象實(shí)例可調(diào)用。
我們在下面的例子中定義了 __add__
dunder 方法,并創(chuàng)建了兩個(gè)實(shí)例
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __str__(self):
return f"({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3) # Output: (4, 6)
我們定義了一個(gè) Point
類,它有 x
、y
兩個(gè)實(shí)例變量以及__add__
方法和__str__
方法
當(dāng)我們使用 + 運(yùn)算符對 Point
的兩個(gè)實(shí)例(p1、p2)求和時(shí),__add__
會(huì)自動(dòng)調(diào)用。它返回一個(gè)新 的 Point
對象(p3),其 x
和 y
值是兩個(gè)原始 Point
對象的 x
和 y
值的和
當(dāng)使用print()
函數(shù)時(shí)調(diào)用自定義的__str__
方法
前導(dǎo)雙下劃線
前導(dǎo)雙下劃線作為前綴在對象名前使用時(shí),表示這是一個(gè)特殊的命名約定,它在類定義中用于創(chuàng)建私有屬性或方法。
當(dāng)在類中使用雙下劃線作為前綴時(shí),Python 解釋器會(huì)自動(dòng)修改屬性名,以避免在子類中發(fā)生命名沖突。這個(gè)過程被稱為名稱修飾(name mangling)
比如下面這個(gè)例子:
class MyClass:
def __init__(self):
self.__private_var = 10
def get_private_var(self):
return self.__private_var
# 創(chuàng)建類的實(shí)例
obj = MyClass()
# 嘗試訪問私有屬性
print(obj.__private_var) # 會(huì)拋出 AttributeError 錯(cuò)誤,因?yàn)檫@個(gè)屬性名稱已被修改
# 通過調(diào)用訪問私有屬性的方法來獲取
print(obj.get_private_var()) # 輸出: 10
__private_var
屬性在類內(nèi)部被訪問,但是在類外部直接訪問會(huì)導(dǎo)致 AttributeError
錯(cuò)誤。
這是因?yàn)?Python 對 __private_var
進(jìn)行了名稱修飾,實(shí)際名稱變成了 obj._MyClass__private_var
,這樣避免了外部直接訪問
但是我們可以通過調(diào)用類內(nèi)部方法 get_private_var()
在類外部訪問私有屬性。
通過使用前導(dǎo)雙下劃線,以確保類的某些屬性或方法只能從類本身內(nèi)部訪問。這有助于防止意外修改重要的內(nèi)部數(shù)據(jù),并使代碼更加可靠和可維護(hù)文章來源:http://www.zghlxwxcb.cn/news/detail-747836.html
但如果你知道修飾后的名稱,你仍可以在類外部去訪問文章來源地址http://www.zghlxwxcb.cn/news/detail-747836.html
到了這里,關(guān)于Python 中的單下劃線和雙下劃線的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!