簡體   English   中英

Python 導入究竟是如何工作的?

[英]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 由於修改列表/字典不會導致任何綁定,因此這些操作將修改原始操作( bfoo.b綁定到您操作的同一對象)。 將新對象分配給b將再次成為綁定操作,從而將bfoo.b分開。

還值得注意的是import語句究竟做了什么:

  • import foo將模塊名稱綁定到當前范圍內的模塊對象,因此如果您修改foo.whatever ,您將使用該模塊中的名稱 - 任何修改/分配都會影響模塊中的變量。
  • from foo import bar僅將給定的名稱(即foo將保持未綁定)綁定到foo具有相同名稱的元素 - 因此對bar操作與前面解釋的一樣。
  • from foo import *行為與前一個類似,但它導入所有沒有下划線前綴的全局名稱。 如果模塊定義了__all__僅導入此序列內的名稱。

第 3 部分(您的問題中甚至不存在:p)

python 文檔非常好,而且通常很冗長 - 您可以在其中找到幾乎所有可能的與語言相關的問題的答案。 以下是一些有用的鏈接:

回答你的第一個問題:

不,python 不會被“導入”兩次。 當 python 加載一個模塊時,它會檢查sys.modules的模塊。 如果它不在那里,則將其放在那里並加載。

回答你的第二個問題:

模塊可以定義它們將導出到from camelot import *場景的名稱,並且行為是為現有值創建名稱,而不是引用現有變量(python 沒有引用)。

在一個有點相關的主題上,執行from camelot import * 與常規 import 不同

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM