背景
關于python的導入的原因一直不是很理解,上網查了一下這個與命名空間有關。所以寫了這樣一篇博客梳理其關系。不同的import會對name作用域產生不同的影響,對namespace界定之后,我們的思路也會更加清晰。
什么是命名空間
命名空間就是可以存放很多name的一個space。
python中的name概念與其他語言中的name概念相似,比如java。但是有一點不同的是由于Python是動態語言,所以一個變量可以指向integer,float類型,還可以指向函數。
比如你可以這樣寫:
def func():
print('func executing...')
f = func
你就可以通過f()訪問func函數。
為了了解命名空間首先需要了解module的概念。
一個module 就是一個python文件,一個module可能包含class,fuction,或者許多names。每一個module有它自己的namespaces(我想這就是推出module的原因所在了吧)
同一個命名空間里不能有相同的名字。
每一個命名空間都是孤立的,所以你可以有兩個module,比如Inter,FloatingPoint都有一個函數為add()。
關于import
我們常見的import 是 import module,from module import someName,from module import
1.先說import module,這是最簡單也是最推薦的一種導入方式。你可以通過module 名字作為前綴來訪問其中的變量。
import os
os.path.exist() ## 你必須以os作為開頭
2.from module import someName
這會把 someName 從 module 的namespace 導入到當前程序的namespace,由于同一個namespace 只能name不能相同,如果你把Integer.add()導入到當前namespace,且當前namespace有add()函數。那么你是無法通過不用前綴(即add())訪問integer.add()的函數。
當然這種情況適合你導入的name少,且當前程序namespace沒有要導入的name。
- form module import *
這會把module 中的所有name都導入到當前的namespace,這會導致命名空間污染。(情況在第二點類似,比如有與當前空間相同的name等等問題)
其三者的區別如下圖所示:
scope
scope為程序中的一塊區域,在這塊區域你不需要通過前綴來訪問,換句話說就是name的影響范圍。scope有很多種,比如module級別,function級別,python builtins。
比如一個定義在module global namespace中的name,可以被這個module中的function class都訪問到,這就相當于java和c++ 其他語言中的全局變量。
這里說明的一點就是一個module就是一個namespace,一個module中可以有很多種scope,class,functio等等。理清他們概念的邊界可以減少我們進入陷阱。