python 類中函數(shù)名前后加下劃線的具體使用
在Python編程語言中,函數(shù)名前后有下劃線是一種常見的命名約定,被廣泛應(yīng)用于類中的函數(shù)。這種命名約定被稱為“下劃線命名風(fēng)格”或“Snake Case”,它有助于提高代碼的可讀性和可維護(hù)性。本文將介紹下劃線命名風(fēng)格的由來、使用場(chǎng)景以及如何正確應(yīng)用它。
下劃線命名風(fēng)格的由來
下劃線命名風(fēng)格起源于Python社區(qū)的一種共識(shí),旨在使代碼更易讀、易理解、易維護(hù)。在Python社區(qū)中,強(qiáng)調(diào)代碼的可讀性,并推崇一致性和語義明確的命名風(fēng)格。下劃線命名風(fēng)格是一種約定俗成的規(guī)范,廣泛應(yīng)用于Python編程中。
下劃線命名風(fēng)格的核心思想是通過在函數(shù)名前后添加下劃線來增強(qiáng)函數(shù)的可讀性。這種命名方式使得函數(shù)名更加清晰、易于理解,并且能夠與其他命名方式進(jìn)行區(qū)分。
使用下劃線命名風(fēng)格的場(chǎng)景
下劃線命名風(fēng)格適用于類中的函數(shù)、方法和變量。下面是一些常見的使用場(chǎng)景:
1. 類中的私有函數(shù)和變量
在Python中,沒有嚴(yán)格的私有函數(shù)和變量的概念。然而,通過在函數(shù)名前面添加一個(gè)下劃線,可以向其他開發(fā)者傳達(dá)出這個(gè)函數(shù)或變量是類內(nèi)部使用的信號(hào)。這樣做有助于防止其他開發(fā)者在未經(jīng)允許的情況下修改或訪問這些函數(shù)和變量。
class MyClass: def _private_function(self): # 這是一個(gè)私有函數(shù),只能在類內(nèi)部訪問 pass def public_function(self): # 這是一個(gè)公共函數(shù),可以從類外部訪問 pass
2. 類中的保護(hù)函數(shù)和變量
在Python中,通過在函數(shù)名前面添加雙下劃線(例如__function_name)可以創(chuàng)建受保護(hù)的函數(shù)和變量。這意味著這些函數(shù)和變量只能在類內(nèi)部或派生類中訪問,而不能從類的外部訪問。
class MyClass: def __protected_function(self): # 這是一個(gè)受保護(hù)的函數(shù),只能在類內(nèi)部或派生類中訪問 pass def public_function(self): # 這是一個(gè)公共函數(shù),可以從類外部訪問 pass
3. 避免命名沖突
在大型項(xiàng)目中,可能存在許多不同的模塊和類。通過在函數(shù)名前面添加類名或模塊名作為前綴,可以避免命名沖突,并使函數(shù)的作用范圍更加明確。
class MyClass: def my_class_function(self): # 這是屬于 MyClass 類的函數(shù) pass class AnotherClass: def my_class_function(self): # 這是屬于 AnotherClass 類的函數(shù) pass
下劃線命名風(fēng)格的注意事項(xiàng)
雖然下劃線命名風(fēng)格可以提高代碼的可讀性和可維護(hù)性,但在使用時(shí)也需要注意以下幾點(diǎn):
1. 遵循PEP 8標(biāo)準(zhǔn)
PEP 8是Python代碼風(fēng)格指南,提供了一套一致性和規(guī)范性的編碼約定。在使用下劃線命名風(fēng)格時(shí),應(yīng)遵循PEP 8標(biāo)準(zhǔn),以確保代碼的一致性和易讀性。
2. 不要濫用下劃線
下劃線命名風(fēng)格應(yīng)該僅用于適當(dāng)?shù)膱?chǎng)景,如私有函數(shù)、保護(hù)函數(shù)和避免命名沖突。濫用下劃線可能導(dǎo)致代碼的冗余和混亂,降低代碼的可讀
補(bǔ):五種下劃線模式
單前導(dǎo)下劃線:_var
Python中并沒有真正意義上的“私有”,類的屬性的的可見性取決于屬性(變量和方法)的名字。
以單下劃線開頭的屬性(例如_spam),應(yīng)被當(dāng)成API中非公有的部分(但是注意,它們?nèi)匀豢梢员辉L問),一般是具體實(shí)現(xiàn)細(xì)節(jié)的部分,修改它們時(shí)無需對(duì)外部通知,需要提供外部接口以供外部調(diào)用。在類中,帶有前導(dǎo)下劃線的名稱只是向其他程序員指示該屬性或方法旨在是私有的。
引用PEP-8:
_single_leading_underscore: weak “internal use” indicator. E.g.
from M import *
does not import objects whose name starts with an underscore.
class BaseForm(StrAndUnicode): ... def _get_errors(self): "Returns an ErrorDict for the data provided for the form" if self._errors is None: self.full_clean() return self._errors errors = property(_get_errors)
該代碼片段來自Django源碼(django/forms/forms.py)。這段代碼的設(shè)計(jì)就是errors屬性是對(duì)外API的一部分,如果你想獲取錯(cuò)誤詳情,應(yīng)該訪問errors屬性,而不是(也不應(yīng)該)訪問_get_errors方法。
(1)約定的內(nèi)部變量
當(dāng)涉及到變量和方法名稱時(shí),單個(gè)下劃線前綴有一個(gè)約定俗成的含義。 它是對(duì)程序員的一個(gè)提示 ,意味著Python社區(qū)一致認(rèn)為它應(yīng)該是什么意思,但程序的行為不受影響。下劃線前綴的含義是告知其他程序員:以單個(gè)下劃線開頭的變量或方法僅供內(nèi)部使用。 該約定在PEP 8中有定義。但這不是Python強(qiáng)制規(guī)定的。 Python不像Java那樣在“私有”和“公共”變量之間有很強(qiáng)的區(qū)別。
看看下面的例子:
class Test: def __init__(self): self.foo = 11 self._bar = 23
如果你實(shí)例化此類,并嘗試訪問在__init__構(gòu)造函數(shù)中定義的foo和_bar屬性,會(huì)發(fā)生什么情況? 讓我們來看看:
>>> t = Test() >>> t.foo 11 >>> t._bar 23
你會(huì)看到_bar中的單個(gè)下劃線并沒有阻止我們“進(jìn)入”類并訪問該變量的值。這是因?yàn)镻ython中的單個(gè)下劃線前綴僅僅是一個(gè)約定,而不是一個(gè)強(qiáng)制性的規(guī)則。至少相對(duì)于變量和方法名而言。
其可以直接訪問。不過根據(jù)python的約定,應(yīng)該將其視作private,而不要在外部使用它們,良好的編程習(xí)慣是不要在外部使用它。
(2)模塊級(jí)私有化
單下劃線常用來實(shí)現(xiàn)模塊級(jí)私有化,當(dāng)我們使用“from mymodule import *”來加載模塊的時(shí)候,不會(huì)加載以單下劃線開頭的模塊屬性。也就是前導(dǎo)下劃線的確會(huì)影響從模塊中導(dǎo)入名稱的方式。
假設(shè)你在一個(gè)名為my_module的模塊中有以下代碼:
# This is my_module.py: def external_func(): return 23 def _internal_func(): return 42
現(xiàn)在,如果使用通配符從模塊中導(dǎo)入所有名稱,則Python不會(huì)導(dǎo)入帶有前導(dǎo)下劃線的名稱(除非模塊定義了覆蓋此行為的__all__列表,模塊或包中的__all__列表顯式地包含了他們):
>>> from my_module import * >>> external_func() 23 >>> _internal_func() NameError: "name '_internal_func' is not defined"
順便說一下,應(yīng)該避免通配符導(dǎo)入,因?yàn)樗鼈兪姑Q空間中存在哪些名稱不清楚,存在重名的變量會(huì)出現(xiàn)混亂。 為了清楚起見,堅(jiān)持常規(guī)導(dǎo)入更好。
與通配符導(dǎo)入不同,常規(guī)導(dǎo)入不受前導(dǎo)單個(gè)下劃線命名約定的影響:
>>> import my_module >>> my_module.external_func() 23 >>> my_module._internal_func() 42
我知道這一點(diǎn)可能有點(diǎn)令人困惑。 如果你遵循PEP 8推薦,避免通配符導(dǎo)入,那么你真正需要記住的只有這個(gè):
單個(gè)下劃線是一個(gè)Python命名約定,表示這個(gè)名稱是供內(nèi)部使用的。 它通常不由Python解釋器強(qiáng)制執(zhí)行,僅僅作為一種對(duì)程序員的提示。
單末尾下劃線:var_
有時(shí)候,一個(gè)變量的最合適的名稱已經(jīng)被一個(gè)關(guān)鍵字所占用。 因此,像class或def這樣的名稱不能用作Python中的變量名稱。 在這種情況下,你可以附加一個(gè)下劃線來解決命名沖突:
>>> def make_object(name, class): SyntaxError: "invalid syntax" >>> def make_object(name, class_): ... pass
總之,單個(gè)末尾下劃線(后綴)是一個(gè)約定,用來避免與Python關(guān)鍵字產(chǎn)生命名沖突。 PEP 8解釋了這個(gè)約定。
雙前導(dǎo)下劃線:__var
雙下劃線用在Python類變量中是Name Mangling。這種特定的行為差不多等價(jià)于Java中的final方法(不能被擠成)和C++中的正常方法(非虛方法)。之前很多人說Python中雙下劃線開頭表示私有。這樣理解可能也不能說錯(cuò),但這不是Python設(shè)計(jì)雙下劃線開頭的初衷和目的,Python設(shè)計(jì)此的真正目的僅僅是為了避免子類覆蓋父類的方法。
《Python學(xué)習(xí)手冊(cè)》的說明,以雙下劃線開頭的變量名,會(huì)自動(dòng)擴(kuò)張(原始的變量名會(huì)在頭部加入一個(gè)下劃線,然后是所在類名稱),從而包含了所在類的名稱。無法被繼承,也無法在外部訪問。必須通過改寫后的變量名或函數(shù)名來訪問。更像是私有變量和私有函數(shù)。當(dāng)然也不是靜態(tài)變量。
(1)防止子類重寫父類屬性
以雙下劃線開頭并最多以一個(gè)下劃線結(jié)尾的變量或函數(shù)(例如___spam),將會(huì)被替換成_classname__spam這樣的形式,其中classname是當(dāng)前類的類名。知道了這點(diǎn)之后,我們?nèi)匀豢梢栽L問到python的私有函數(shù)
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.
和來自同一頁面的警告:
Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
到目前為止,我們所涉及的所有命名模式的含義,來自于已達(dá)成共識(shí)的約定。 而對(duì)于以雙下劃線開頭的Python類的屬性(包括變量和方法),情況就有點(diǎn)不同了。
雙下劃線前綴會(huì)導(dǎo)致Python解釋器重寫屬性名稱,以避免子類中的命名沖突。這也叫做名稱修飾(name mangling) - 解釋器更改變量的名稱,以便在類被擴(kuò)展的時(shí)候不容易產(chǎn)生沖突。
我知道這聽起來很抽象。 因此,我組合了一個(gè)小小的代碼示例來予以說明:
class Test: def __init__(self): self.foo = 11 self._bar = 23 self.__baz = 23
讓我們用內(nèi)置的dir()函數(shù)來看看這個(gè)對(duì)象的屬性:
>>> t = Test() >>> dir(t) ['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bar', 'foo']
以上是這個(gè)對(duì)象屬性的列表。 讓我們來看看這個(gè)列表,并尋找我們的原始變量名稱foo,_bar和__baz - 我保證你會(huì)注意到一些有趣的變化。
- self.foo變量在屬性列表中顯示為未修改為foo。
- self._bar的行為方式相同 - 它以_bar的形式顯示在類上。 就像我之前說過的,在這種情況下,前導(dǎo)下劃線僅僅是一個(gè)約定。 給程序員一個(gè)提示而已。
- 然而,對(duì)于self.__baz而言,情況看起來有點(diǎn)不同。 當(dāng)你在該列表中搜索__baz時(shí),你會(huì)看不到有這個(gè)名字的變量。
__baz出什么情況了?
如果你仔細(xì)觀察,你會(huì)看到此對(duì)象上有一個(gè)名為_Test__baz的屬性。 這就是Python解釋器所做的名稱修飾。 它這樣做是為了防止變量在子類中被重寫。
讓我們創(chuàng)建另一個(gè)擴(kuò)展Test類的類,并嘗試重寫構(gòu)造函數(shù)中添加的現(xiàn)有屬性:
class ExtendedTest(Test): def __init__(self): super().__init__() self.foo = 'overridden' self._bar = 'overridden' self.__baz = 'overridden'
現(xiàn)在,你認(rèn)為foo,_bar和__baz的值會(huì)出現(xiàn)在這個(gè)ExtendedTest類的實(shí)例上嗎? 我們來看一看:
>>> t2 = ExtendedTest() >>> t2.foo 'overridden' >>> t2._bar 'overridden' >>> t2.__baz AttributeError: "'ExtendedTest' object has no attribute '__baz'"
等一下,當(dāng)我們嘗試查看t2 .__ baz的值時(shí),為什么我們會(huì)得到AttributeError? 名稱修飾被再次觸發(fā)了! 事實(shí)證明,這個(gè)對(duì)象甚至沒有__baz屬性:
>>> dir(t2) ['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']
正如你可以看到__baz變成_ExtendedTest__baz以防止意外修改:
>>> t2._ExtendedTest__baz 'overridden'
但原來的_Test__baz還在:
>>> t2._Test__baz 42
雙下劃線名稱修飾對(duì)程序員是完全透明的。 下面的例子證實(shí)了這一點(diǎn):
class ManglingTest: def __init__(self): self.__mangled = 'hello' def get_mangled(self): return self.__mangled >>> ManglingTest().get_mangled() 'hello' >>> ManglingTest().__mangled AttributeError: "'ManglingTest' object has no attribute '__mangled'"
名稱修飾是否也適用于方法名稱? 是的,也適用。名稱修飾會(huì)影響在一個(gè)類的上下文中,以兩個(gè)下劃線字符("dunders")開頭的所有名稱:
class MangledMethod: def __method(self): return 42 def call_it(self): return self.__method() >>> MangledMethod().__method() AttributeError: "'MangledMethod' object has no attribute '__method'" >>> MangledMethod().call_it() 42
這是另一個(gè)也許令人驚訝的運(yùn)用名稱修飾的例子:
_MangledGlobal__mangled = 23 class MangledGlobal: def test(self): return __mangled >>> MangledGlobal().test() 23
在這個(gè)例子中,我聲明了一個(gè)名為_MangledGlobal__mangled的全局變量。然后我在名為MangledGlobal的類的上下文中訪問變量。由于名稱修飾,我能夠在類的test()方法內(nèi),以__mangled來引用_MangledGlobal__mangled全局變量。 Python解釋器自動(dòng)將名稱__mangled擴(kuò)展為_MangledGlobal__mangled,因?yàn)樗詢蓚€(gè)下劃線字符開頭。這表明名稱修飾不是專門與類屬性關(guān)聯(lián)的。它適用于在類上下文中使用的兩個(gè)下劃線字符開頭的任何名稱。
(2)示例
class A(object): def __method(self): print("I'm a method in class A") def method_x(self): print("I'm another method in class A\n") def method(self): self.__method() self.method_x() class B(A): def __method(self): print("I'm a method in class B") def method_x(self): print("I'm another method in class B\n") if __name__ == '__main__': print("situation 1:") a = A() a.method() b = B() b.method() print("situation 2:") # a.__method() a._A__method()
執(zhí)行結(jié)果:
situation 1:
I'm a method in class A
I'm another method in class A
I'm a method in class A
I'm another method in class B
situation 2:
I'm a method in class A
這里有兩個(gè)點(diǎn)需要注意:
A類中我們定義了__method()、method_x和method()三個(gè)方法;然后我們重新定義一個(gè)類B,繼承自A,并且在B類中覆寫(override)了其父類的__method()和method_x方法,但是從輸出結(jié)果看,B對(duì)象調(diào)用method()方法時(shí)調(diào)用了其父類A的__method()方法和自己的method_x()方法。也就是說,__method()覆寫沒有生效,而method_x()覆寫生效了。而這也正是Python設(shè)計(jì)雙下劃線開頭的唯一目的。
前面我們就說了,Python中不存在真正意義上的私有變量。對(duì)于雙下劃線開頭的方法和屬性雖然我們不能直接引用,那是因?yàn)镻ython默認(rèn)在其前面加了前綴_類名,所以就像situation 2下面的代碼,雖然我們不能用a直接訪問__method(),但卻可以加上前綴去訪問,即_A__method()。
Python的私有變量軋壓:
Python把以兩個(gè)或以上下劃線字符開頭且沒有以兩個(gè)或以上下劃線結(jié)尾的變量當(dāng)作私有變量。私有變量會(huì)在代碼生成之前被轉(zhuǎn)換為長(zhǎng)格式(變?yōu)楣校?。轉(zhuǎn)換機(jī)制是這樣的:在變量前端插入類名,再在前端加入一個(gè)下劃線字符。這就是所謂的私有變量軋壓(Private name mangling)。
注意:一是因?yàn)檐垑簳?huì)使標(biāo)識(shí)符變長(zhǎng),當(dāng)超過255的時(shí)候,Python會(huì)切斷,要注意因此引起的命名沖突。
二是當(dāng)類名全部以下劃線命名(如___)的時(shí)候,Python就不再執(zhí)行軋壓。
具體原因:因?yàn)轭怉定義了一個(gè)私有成員函數(shù)(變量),所以在代碼生成之前先執(zhí)行私有變量軋壓。軋壓之后,類A的代碼就變成這樣了:
class A(object): def _A__method(self): # 這行變了 print("I'm a method in class A") def method_x(self): print("I'm another method in class A\n") def method(self): self._A__method() # 這行變了 self.method_x()
有點(diǎn)像C語言里的宏展開。因?yàn)樵陬怋定義的時(shí)候沒有覆蓋__init__方法,所以調(diào)用的仍然是A.__init__,即執(zhí)行了self._A__method(),自然輸出“I'm a method in class A”了。
下面的兩段代碼可以增加說服力,增進(jìn)理解:
class A(object): def __init__(self): self.__private() self.public() def __private(self): print 'A.__private()' def public(self): print 'A.public()' class B(A): def __private(self): print 'B.__private()' def public(self): print 'B.public()' b = B() A.__private() B.public()
原因與上述相同。類 A里的__private標(biāo)識(shí)符將被轉(zhuǎn)換為_A__private,這就是_A__private和__private消失的原因了。
class C(A): def __init__(self): # 重寫 __init__ ,不再調(diào)用 self._A__private self.__private() # 這里綁定的是 _C_private self.public() def __private(self): print 'C.__private()' def public(self): print 'C.public()' c = C() C.__private() C.public()
可以看出重寫 __init__ ,不再調(diào)用 self._A__private,而是調(diào)用類C里__init__函數(shù)里綁定的_C_private。
而且在類A中也可以直接調(diào)用self._A__method(),雖然該變量未定義,但是進(jìn)行命名改編時(shí)會(huì)修改。
雙前導(dǎo)和末尾下劃線:__var__
如果一個(gè)名字同時(shí)以雙下劃線開始和結(jié)束,則不會(huì)應(yīng)用名稱修飾。 由雙下劃線前綴和后綴包圍的變量不會(huì)被Python解釋器修改:
class PrefixPostfixTest: def __init__(self): self.__bam__ = 42 >>> PrefixPostfixTest().__bam__ 42
但是,Python保留了有雙前導(dǎo)和雙末尾下劃線的名稱,用于特殊用途。 前后有雙下劃線表示的是特殊函數(shù)。通常可以復(fù)寫這些方法實(shí)現(xiàn)自己所需要的功能。
這樣的例子有,__init__ --- 對(duì)象構(gòu)造函數(shù),__call__ --- 它使得一個(gè)對(duì)象可以被調(diào)用。表示這是Python自己調(diào)用的,程序員不要調(diào)用。比如我們可以調(diào)用len()函數(shù)來求長(zhǎng)度,其實(shí)它后臺(tái)是調(diào)用了__len__()方法。一般我們應(yīng)該使用len,而不是直接使用__len__()。
我們一般稱__len__()這種方法為magic methods(魔術(shù)方法),一些操作符后臺(tái)調(diào)用的也是也是這些magic methods,比如+后臺(tái)調(diào)用的是__add__,-調(diào)用的是__sub__,所以這種機(jī)制使得我們可以在自己的類中覆寫操作符(見后面例子)。另外,有的時(shí)候這種開頭結(jié)尾雙下劃線方法僅僅是某些特殊場(chǎng)景的回調(diào)函數(shù),比如__init__()會(huì)在對(duì)象的初始化時(shí)調(diào)用,__new__()會(huì)在構(gòu)建一個(gè)實(shí)例的時(shí)候調(diào)用等等。
- 類內(nèi)置函數(shù)和全局內(nèi)置函數(shù)
- 標(biāo)識(shí)符等的實(shí)現(xiàn)細(xì)節(jié)
- 回調(diào)函數(shù)
class CrazyNumber(object): def __init__(self, n): self.n = n def __add__(self, other): return self.n - other def __sub__(self, other): return self.n + other def __str__(self): return str(self.n) num = CrazyNumber(10) print(num) # output is: 10 print(num + 5) # output is: 5 print(num - 20) # output is: 30
在上面這個(gè)例子中,我們重寫了+
和-
操作符,將他們的功能交換了。
單下劃線:_
(1)臨時(shí)變量
按照習(xí)慣,有時(shí)候單個(gè)獨(dú)立下劃線是用作一個(gè)名字,來表示某個(gè)變量是臨時(shí)的或無關(guān)緊要的。作為臨時(shí)性的名稱使用,但是在后面不會(huì)再次用到該名稱。這種用法在循環(huán)中會(huì)經(jīng)常用到。
例如,在下面的循環(huán)中,我們不需要訪問正在運(yùn)行的索引,我們可以使用“_”來表示它只是一個(gè)臨時(shí)值:
>>> for _ in range(32): ... print('Hello, World.')
你也可以在拆分(unpacking)表達(dá)式(對(duì)元組以逗號(hào)分隔開的表達(dá)式)中將單個(gè)下劃線用作“不關(guān)心的”變量,以忽略特定的值。 同樣,這個(gè)含義只是“依照約定”,并不會(huì)在Python解釋器中觸發(fā)特殊的行為。 單個(gè)下劃線僅僅是一個(gè)有效的變量名稱,會(huì)有這個(gè)用途而已。
在下面的代碼示例中,我將汽車元組拆分為單獨(dú)的變量,但我只對(duì)顏色和里程值感興趣。 但是,為了使拆分表達(dá)式成功運(yùn)行,我需要將包含在元組中的所有值分配給變量。 在這種情況下,“_”作為占位符變量可以派上用場(chǎng):
>>> car = ('red', 'auto', 12, 3812.4) >>> color, _, _, mileage = car >>> color 'red' >>> mileage 3812.4 >>> _ 12
(2)_代表交互式解釋器會(huì)話中上一條的執(zhí)行結(jié)果
除了用作臨時(shí)變量之外,“_”是大多數(shù)Python REPL中的一個(gè)特殊變量,它表示由解釋器執(zhí)行的最近一個(gè)表達(dá)式的結(jié)果。這種用法有點(diǎn)類似于Linux中的上一條命令的用法。只不過在在Python解釋器中表示的上一條執(zhí)行的結(jié)果。這種用法首先被標(biāo)準(zhǔn)CPython解釋器采用,然后其他類型的解釋器也先后采用。
這樣就很方便了,比如你可以在一個(gè)解釋器會(huì)話中訪問先前計(jì)算的結(jié)果,或者,你是在動(dòng)態(tài)構(gòu)建多個(gè)對(duì)象并與它們交互,無需事先給這些對(duì)象分配名字:
>>> 20 + 3 23 >>> _ 23 >>> print(_) 23 >>> list() [] >>> _.append(1) >>> _.append(2) >>> _.append(3) >>> _ [1, 2, 3]
(3)國(guó)際化
也許你也曾看到”_“會(huì)被作為一個(gè)函數(shù)來使用。這種情況下,它通常用于實(shí)現(xiàn)國(guó)際化和本地化字符串之間翻譯查找的函數(shù)名稱,這似乎源自并遵循相應(yīng)的C約定。
from django.utils.translation import ugettext as _ from django.http import HttpResponse def my_view(request): output = _("Welcome to my site.") return HttpResponse(output)
場(chǎng)景一和場(chǎng)景三中的使用方法可能會(huì)相互沖突,所以我們需要避免在使用“_”作為國(guó)際化查找轉(zhuǎn)換功能的代碼塊中同時(shí)使用“_”作為臨時(shí)名稱。
到此這篇關(guān)于python 類中函數(shù)名前后加下劃線的具體使用的文章就介紹到這了,更多相關(guān)python 函數(shù)名加下劃線內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)決策樹并且使用Graphviz可視化的例子
今天小編就為大家分享一篇Python實(shí)現(xiàn)決策樹并且使用Graphviz可視化的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python+pytorch實(shí)現(xiàn)天氣識(shí)別
這篇文章主要為大家詳細(xì)介紹了如何利用Python+pytorch實(shí)現(xiàn)天氣識(shí)別功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-10-10python可以美化表格數(shù)據(jù)輸出結(jié)果的兩個(gè)工具
這篇文章主要介紹了python可以美化表格數(shù)據(jù)輸出結(jié)果的兩個(gè)工具,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06一文搞懂Python中Pandas數(shù)據(jù)合并
pandas是基于NumPy的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。Pandas納入了大量庫和一些標(biāo)準(zhǔn)的數(shù)據(jù)模型,提供了高效操作大型數(shù)據(jù)集的工具。pandas提供大量快速便捷地處理數(shù)據(jù)的函數(shù)和方法。你很快就會(huì)發(fā)現(xiàn),它是使Python強(qiáng)大而高效的數(shù)據(jù)分析環(huán)境的重要因素之一2021-11-11python 經(jīng)緯度求兩點(diǎn)距離、三點(diǎn)面積操作
這篇文章主要介紹了python 經(jīng)緯度求兩點(diǎn)距離、三點(diǎn)面積操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06python使用多線程查詢數(shù)據(jù)庫的實(shí)現(xiàn)示例
這篇文章主要介紹了python使用多線程查詢數(shù)據(jù)庫的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08詳細(xì)介紹在pandas中創(chuàng)建category類型數(shù)據(jù)的幾種方法
這篇文章主要介紹了詳細(xì)介紹在pandas中創(chuàng)建category類型數(shù)據(jù)的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Python實(shí)現(xiàn)的ftp服務(wù)器功能詳解【附源碼下載】
這篇文章主要介紹了Python實(shí)現(xiàn)的ftp服務(wù)器功能,結(jié)合實(shí)例形式分析了Python構(gòu)建ftp服務(wù)器功能的相關(guān)設(shè)置、實(shí)現(xiàn)技巧與操作注意事項(xiàng),并附帶源碼供讀者下載參考,需要的朋友可以參考下2019-06-06