python中的下划线是啥意思?
本文將討論Python中下劃線(_)字符的使用方法。我們將會看到,正如Python中的很多事情,下劃線的不同用法大多數(并非所有)只是常用慣例而已。
單下劃線(_)
通常情況下,會在以下3種場景中使用:
1、在解釋器中:在這種情況下,“_”代表交互式解釋器會話中上一條執行的語句的結果。這種用法首先被標準CPython解釋器采用,然后其他類型的解釋器也先后采用。
>>> _ Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '_' is not defined >>> 42 >>> _ 42 >>> 'alright!' if _ else ':(' 'alright!' >>> _ 'alright!' 2、 作為一個名稱 :這與上面一點稍微有些聯系,此時“_”作為臨時性的名稱使用。這樣,當其他人閱讀你的代碼時將會知道,你分配了一個特定的名稱,但是并不會在后面再次用到該名稱。例如,下面的例子中,你可能對循環計數中的實際值并不感興趣,此時就可以使用“_”。
n = 42 for _ in range(n): do_something()
3、國際化:也許你也曾看到”_“會被作為一個函數來使用。這種情況下,它通常用于實現國際化和本地化字符串之間翻譯查找的函數名稱,這似乎源自并遵循相應的C約定。例如,在Django文檔“轉換”章節中,你將能看到如下代碼:
from django.utils.translation import ugettext as _ from django.http import HttpResponse def my_view(request): output = _("Welcome to my site.") return HttpResponse(output)
可以發現,場景二和場景三中的使用方法可能會相互沖突,所以我們需要避免在使用“_”作為國際化查找轉換功能的代碼塊中同時使用“_”作為臨時名稱。
名稱前的單下劃線(如:_shahriar)
程序員使用名稱前的單下劃線,用于指定該名稱屬性為“私有”。這有點類似于慣例,為了使其他人(或你自己)使用這些代碼時將會知道以“_”開頭的名稱只供內部使用。正如Python文檔中所述:
以下劃線“_”為前綴的名稱(如_spam)應該被視為API中非公開的部分(不管是函數、方法還是數據成員)。此時,應該將它們看作是一種實現細節,在修改它們時無需對外部通知。
正如上面所說,這確實類似一種慣例,因為它對解釋器來說確實有一定的意義,如果你寫了代碼“from <模塊/包名> import *”,那么以“_”開頭的名稱都不會被導入,除非模塊或包中的“__all__”列表顯式地包含了它們。了解更多請查看“Importing * in Python”。
名稱前的雙下劃線(如:__shahriar)
名稱(具體為一個方法名)前雙下劃線(__)的用法并不是一種慣例,對解釋器來說它有特定的意義。Python中的這種用法是為了避免與子類定義的名稱沖突。Python文檔指出,“__spam”這種形式(至少兩個前導下劃線,最多一個后續下劃線)的任何標識符將會被“_classname__spam”這種形式原文取代,在這里“classname”是去掉前導下劃線的當前類名。例如下面的例子:
>>> class A(object): ... def _internal_use(self): ... pass ... def __method_name(self): ... pass ... >>> dir(A()) ['_A__method_name', ..., '_internal_use']
正如所預料的,“_internal_use”并未改變,而“__method_name”卻被變成了“_ClassName__method_name”。此時,如果你創建A的一個子類B,那么你將不能輕易地覆寫A中的方法“__method_name”。
>>> class B(A): ... def __method_name(self): ... pass ... >>> dir(B()) ['_A__method_name', '_B__method_name', ..., '_internal_use']
這里的功能幾乎和Java中的final方法和C++類中標準方法(非虛方法)一樣。
名稱前后的雙下劃線(如:__init__)
這種用法表示Python中特殊的方法名。其實,這只是一種慣例,對Python系統來說,這將確保不會與用戶自定義的名稱沖突。通常,你將會覆寫這些方法,并在里面實現你所需要的功能,以便Python調用它們。例如,當定義一個類時,你經常會覆寫“__init__”方法。
雖然你也可以編寫自己的特殊方法名,但不要這樣做。
>>> class C(object): ... def __mine__(self): ... pass ... >>> dir(C) ... [..., '__mine__', ...]
其實,很容易擺脫這種類型的命名,而只讓Python內部定義的特殊名稱遵循這種約定。
問一:下劃線變量
單下劃線開頭的變量,Pyhthon規定為內部變量(私有變量),from M import * 時,這種變量并不會導入進來,例如:
foo.py#foo.py bar = 10 bar2 = 11 _bar = 20 __bar = 30 foo2.py#foo2.py from foo import * if __name__ == '__main__':print locals()執行 python foo2.py,輸出:
{'bar2': 11, 'bar': 10, '...省略'}輸入結果中并沒有 _bar和__bar,因為它們都是以下劃線開頭的變量,所以沒有導入進來,但是如果你非要把這些變量導入進來也是可以的,使用import時,明確導入具體的變量時就行了。如:
#foo2.py from foo import * from foo import _bar from foo import __bar if __name__ == '__main__':print locals()輸出:
{'_bar': 20, 'bar2': 11, 'bar': 10, '__bar': 30, ‘...省略'}單下劃線結尾的變量:用于避免于Python關鍵字沖突的變量,如class_:
Tkinter.Toplevel(master, class_='ClassName')
如上所說的變量講的是定義在模塊中的變量,屬于模塊中的屬性,如果這些變量定義在函數里面,那它和普通的變量沒什么兩樣的,都是局部變量。此外,單下劃線同樣適用于函數。
雙下劃線開頭的變量:它在模塊中還是當作單下劃線看待,但出現在類中作為類屬性就不一樣了,在運行時該類屬性會被“混淆",不能直接訪問,需要在該變量前加上下劃線和類名才能訪問。如:
class Foo(object):boo = 40_boo = 50 __boo = 60 # _Foo__boo def __init__(self):self.__booo = 70def __test(self): #_Foo__testprint "__test"if __name__ == '__main__':print Foo.booprint Foo._booprint Foo._Foo__boofoo = Foo()print foo._Foo__booofoo._Foo__test()這樣可以防止與父類或子類中同名的__xxx屬性發生沖突。
開始和結尾都有的雙下劃線的變量:此類變量屬于魔法對象,如:init,file,你永遠不要自己也發明個出來。
問二:ALL
__all__對象是裝有字符串的列表對象,他會覆蓋 from?import * 的默認行為:如
#foo.py __all__ = ['bar', 'baz']waz = 5 bar = 10 def baz(): return 'baz' from foo import *print bar print baz# 異常 print waz在foo.py里面定義了__all__后,import * 就會按照 __all__定義的內容導入,所以這里 print waz就拋異常了,因為它不在 __all__里面。為外,你可以把下劃線開頭的變量的字符串形式加入到__all__中,這樣 import * 也能看到這些變量。
參考:
http://foofish.net/python.html總結
以上是生活随笔為你收集整理的python中的下划线是啥意思?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C语言】用递归编写程序计算Hermit
- 下一篇: MP4和HR-HDTV压制教程