背景
關(guān)于python的導(dǎo)入的原因一直不是很理解,上網(wǎng)查了一下這個(gè)與命名空間有關(guān)。所以寫了這樣一篇博客梳理其關(guān)系陨晶。不同的import會(huì)對(duì)name作用域產(chǎn)生不同的影響,對(duì)namespace界定之后帝璧,我們的思路也會(huì)更加清晰珍逸。
什么是命名空間
命名空間就是可以存放很多name的一個(gè)space。
python中的name概念與其他語言中的name概念相似聋溜,比如java谆膳。但是有一點(diǎn)不同的是由于Python是動(dòng)態(tài)語言,所以一個(gè)變量可以指向integer,float類型撮躁,還可以指向函數(shù)漱病。
比如你可以這樣寫:
def func():
print('func executing...')
f = func
你就可以通過f()訪問func函數(shù)。
為了了解命名空間首先需要了解module的概念把曼。
一個(gè)module 就是一個(gè)python文件杨帽,一個(gè)module可能包含class,fuction,或者許多names。每一個(gè)module有它自己的namespaces(我想這就是推出module的原因所在了吧)
同一個(gè)命名空間里不能有相同的名字嗤军。
每一個(gè)命名空間都是孤立的注盈,所以你可以有兩個(gè)module,比如Inter,FloatingPoint都有一個(gè)函數(shù)為add()叙赚。
關(guān)于import
我們常見的import 是 import module,from module import someName,from module import
1.先說import module老客,這是最簡單也是最推薦的一種導(dǎo)入方式僚饭。你可以通過module 名字作為前綴來訪問其中的變量。
import os
os.path.exist() ## 你必須以os作為開頭
2.from module import someName
這會(huì)把 someName 從 module 的namespace 導(dǎo)入到當(dāng)前程序的namespace胧砰,由于同一個(gè)namespace 只能name不能相同鳍鸵,如果你把Integer.add()導(dǎo)入到當(dāng)前namespace,且當(dāng)前namespace有add()函數(shù)尉间。那么你是無法通過不用前綴(即add())訪問integer.add()的函數(shù)偿乖。
當(dāng)然這種情況適合你導(dǎo)入的name少,且當(dāng)前程序namespace沒有要導(dǎo)入的name哲嘲。
- form module import *
這會(huì)把module 中的所有name都導(dǎo)入到當(dāng)前的namespace贪薪,這會(huì)導(dǎo)致命名空間污染。(情況在第二點(diǎn)類似眠副,比如有與當(dāng)前空間相同的name等等問題)
其三者的區(qū)別如下圖所示:
scope
scope為程序中的一塊區(qū)域画切,在這塊區(qū)域你不需要通過前綴來訪問己单,換句話說就是name的影響范圍荆针。scope有很多種,比如module級(jí)別,function級(jí)別光涂,python builtins。
比如一個(gè)定義在module global namespace中的name拧烦,可以被這個(gè)module中的function class都訪問到忘闻,這就相當(dāng)于java和c++ 其他語言中的全局變量。
這里說明的一點(diǎn)就是一個(gè)module就是一個(gè)namespace恋博,一個(gè)module中可以有很多種scope齐佳,class,functio等等。理清他們概念的邊界可以減少我們進(jìn)入陷阱债沮。