天天看點

11.8 Python __all__變量用法

事實上,當我們向檔案導入某個子產品時,導入的是該子產品中那些名稱不以下劃線(單下劃線“_”或者雙下劃線“__”)開頭的變量、函數和類。是以,如果我們不想子產品檔案中的某個成員被引入到其它檔案中使用,可以在其名稱前添加下劃線。

以前面章節中建立的 demo.py 子產品檔案和 test.py 檔案為例(它們位于同一目錄),各自包含的内容如下所示:

#demo.py
def say():
    print("人生苦短,我學Python!")

def CLanguage():
    print("C語言中文網:http://www.baidu.com")

def disPython():
    print("Python教程:http://www.baidu.com/python")


#test.py
from demo import *

say()
CLanguage()
disPython()
           

執行 test.py 檔案,輸出結果為:

人生苦短,我學Python!
C語言中文網:http://www.baidu.com
Python教程:http://www.baidu.com/python
           

在此基礎上,如果 demo.py 子產品中的

disPython()

函數不想讓其它檔案引入,則隻需将其名稱改為

_disPython()

或者

__disPython()

。修改之後,再次執行 test.py,其輸出結果為:

人生苦短,我學Python!
C語言中文網:http://www.baidu.com
Traceback (most recent call last):
 File "C:/Users/mengma/Desktop/2.py", line 4, in <module>
  disPython()
NameError: name 'disPython' is not defined
           

顯然,test.py 檔案中無法使用未引入的 disPython() 函數。

Python子產品all變量

除此之外,還可以借助子產品提供的

__all__

變量,該變量的值是一個清單,存儲的是目前子產品中一些成員(變量、函數或者類)的名稱。通過在子產品檔案中設定

__all__

變量,當其它檔案以“from 子產品名 import *”的形式導入該子產品時,該檔案中隻能使用

__all__

清單中指定的成員。

也就是說,隻有以“from 子產品名 import *”形式導入的子產品,當該子產品設有

__all__

變量時,隻能導入該變量指定的成員,未指定的成員是無法導入的。

舉個例子,修改 demo.py 子產品檔案中的代碼:

def say():
    print("人生苦短,我學Python!")

def CLanguage():
    print("C語言中文網:http://www.baidu.com")

def disPython():
    print("Python教程:http://www.baidu.com/python")

 __all__= ["say","CLanguage"]
           

可見,

__all__

變量隻包含 say() 和 CLanguage() 的函數名,不包含 disPython() 函數的名稱。此時直接執行 test.py 檔案,其執行結果為:

人生苦短,我學Python!
C語言中文網:http://www.baidu.com
Traceback (most recent call last):
 File "C:/Users/mengma/Desktop/2.py", line 4, in <module>
  disPython()
NameError: name 'disPython' is not defined
           

顯然,對于 test.py 檔案來說,demo.py 子產品中的 disPython() 函數是未引入,這樣調用是非法的。

再次聲明,

__all__

變量僅限于在其它檔案中以“from 子產品名 import *”的方式引入。也就是說,如果使用以下 2 種方式引入子產品,則

__all__

變量的設定是無效的。

  1. 以“import 子產品名”的形式導入子產品。通過該方式導入子產品後,總可以通過子產品名字首(如果為子產品指定了别名,則可以使用模快的别名作為字首)來調用子產品内的所有成員(除了以下劃線開頭命名的成員)。

仍以 demo.py 子產品檔案和 test.py 檔案為例,修改它們的代碼如下所示:

#demo.py

def say():
    print("人生苦短,我學Python!")

def CLanguage():
    print("C語言中文網:http://www.baidu.com")

def disPython():
    print("Python教程:http://www.baidu.com/python") 

__all__= ["say"]


#test.py
import demo

demo.say()
demo.CLanguage()
demo.disPython()
           

運作 test.py 檔案,其輸出結果為:

人生苦短,我學Python!
C語言中文網:http://www.baidu.com
Python教程:http://www.baidu.com/python
           

可以看到,雖然 demo.py 子產品檔案中設定有

__all__

變量,但是當以“import demo”的方式引入後,

__all__

變量将不起作用。

  1. 以“from 子產品名 import 成員”的形式直接導入指定成員。使用此方式導入的子產品,

    __all__

    變量即便設定,也形同虛設。

仍以 demo.py 和 test.py 為例,修改 test.py 檔案中的代碼,如下所示:

from demo import say
from demo import CLanguage
from demo import disPython

say()
CLanguage()
disPython()
           

運作 test.py,輸出結果為:

人生苦短,我學Python!
C語言中文網:http://www.baidu.com
Python教程:http://www.baidu.com/python