1. 程式人生 > >Python中下劃線的變數是什麼個意思

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 = 70

    def __test(self):   #_Foo__test
        print "__test"

if __name__ == '__main__':
    print
Foo.boo print Foo._boo print Foo._Foo__boo foo = Foo() print foo._Foo__booo foo._Foo__test()

這樣可以防止與父類或子類中同名的__xxx屬性發生衝突。

開始和結尾都有的雙下劃線的變數:此類變數屬於魔法物件,如:initfile,你永遠不要自己也發明個出來。

問二: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 * 也能看到這些變數。


關注公眾號「Python之禪」(id:vttalk)獲取最新文章 python之禪