[英]How does Python importing exactly work?
我有兩種特定情況,我不明白 Python 中的導入是如何工作的:
一、具體情況:
當我在兩個不同的 Python 腳本中導入同一個模塊時,該模塊不會被導入兩次,對嗎? Python第一次遇到就導入,第二次是檢查模塊是否已經導入,還是復制了?
二、具體情況:
考慮以下名為bla.py
模塊:
a = 10
然后,我們有foo.py
,一個導入bla.py
的模塊:
from bla import *
def Stuff ():
return a
之后,我們有一個名為bar.py
的腳本,它由用戶執行:
from foo import *
Stuff() #This should return 10
a = 5
Stuff()
這里我不知道: Stuff()
返回 10 還是 5?
第1部分
該模塊只加載一次,因此再次導入不會有性能損失。 如果您確實希望再次加載/解析它,則必須reload()
模塊。
首先檢查的是
sys.modules
,這是之前導入的所有模塊的緩存。 [來源]
第2部分
from foo import *
a
from foo import *
到本地范圍。 為a
賦值時,它會被新值替換 - 但原始foo.a
變量沒有被觸及。
因此,除非您import foo
並修改foo.a
,否則兩個調用都將返回相同的值。
對於諸如列表或字典之類的可變類型,它會有所不同,修改它確實會影響原始變量 - 但為其分配新值仍然不會修改foo.whatever
。
如果您需要更詳細的信息,請查看http://docs.python.org/reference/executionmodel.html :
以下構造綁定名稱:函數的形式參數、導入語句、類和函數定義(這些綁定定義塊中的類或函數名稱),以及作為標識符的目標(如果出現在賦值、for 循環頭、第二個中)在 with 語句中,except 子句標題或之后的位置。
兩個粗體部分與您相關:首先,名稱a
在導入期間綁定到foo.a
的值。 然后,在執行a = 5
,名稱a
綁定到5
。 由於修改列表/字典不會導致任何綁定,因此這些操作將修改原始操作( b
和foo.b
綁定到您操作的同一對象)。 將新對象分配給b
將再次成為綁定操作,從而將b
與foo.b
分開。
還值得注意的是import
語句究竟做了什么:
import foo
將模塊名稱綁定到當前范圍內的模塊對象,因此如果您修改foo.whatever
,您將使用該模塊中的名稱 - 任何修改/分配都會影響模塊中的變量。from foo import bar
僅將給定的名稱(即foo
將保持未綁定)綁定到foo
具有相同名稱的元素 - 因此對bar
操作與前面解釋的一樣。from foo import *
行為與前一個類似,但它導入所有沒有下划線前綴的全局名稱。 如果模塊定義了__all__
僅導入此序列內的名稱。第 3 部分(您的問題中甚至不存在:p)
python 文檔非常好,而且通常很冗長 - 您可以在其中找到幾乎所有可能的與語言相關的問題的答案。 以下是一些有用的鏈接:
import
, yield
)for
、 try
、 with
)回答你的第一個問題:
不,python 不會被“導入”兩次。 當 python 加載一個模塊時,它會檢查sys.modules
的模塊。 如果它不在那里,則將其放在那里並加載。
回答你的第二個問題:
模塊可以定義它們將導出到from camelot import *
場景的名稱,並且行為是為現有值創建名稱,而不是引用現有變量(python 沒有引用)。
在一個有點相關的主題上,執行from camelot import *
與常規 import 不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.