2015-06-10 54 views
2

我想知道爲什麼在python(python 3.4)中導入變量的結果與導入模塊然後引用的結果不同,更多的是爲什麼進行了深層複製 - 還有一種繞過副本的方法(而不是通過定義一個簡單地返回它的函數)?導入變量初始化

a.py

v = 1 

def set(): 
    global v 
    v = 3 

main.py

import a 
import b 

a.set() 
b.foo() 

b.py

from a import v 

def foo(): 
    print(v) 
    print(a.v) 
    print(id(v)) 
    print(id(a.v)) 

輸出

1 
3 
1585041872 
1585041904 
+0

所以你想改變從調用代碼導入模塊的狀態。爲什麼? –

+0

配置 - 我想要讀取配置,然後再訪問它。 –

+0

通過調用代碼更改動態配置? –

回答

2

的問題是,你正在修改一個標量值。這不是特定於模塊的問題,只需將該變量傳遞給函數並在其中進行修改即可。

1a,期間導入。無論你在a之後做什麼都不會修改該值,因爲它是一個簡單的不可變的標量值。

如果a.v是一個對象,改變該對象會傳播到任何變量保持它的一個引用。

+2

只是爲了闡明:對象的更改會傳播,但將變量重新綁定到另一個對象則不會。 – bereal

1

讓我們來看看事件的順序:

a.v = 1  # a.py: v = 1 
b.v = a.v # b.py: from a import v 
a.v = 3  # a.set() 
print(b.v) # foo(): print(v) 
print(a.v) # foo(): print(a.v) 

正如你所看到的,其實from a import v結合b.va,和原來的變量之後修改不會影響副本。

0

當您說import a時,您正在創建對模塊的引用。 a.v不會被複制。我在所有模塊中都注意到在一個模塊中進行更改。當您說from a import v時,您正在導入時製作v的副本。如果其中任何一個變量被改變,它都不會反映在別處。

1

自己問了一個duplicate question,並且在別人的幫助下,我弄清楚它是什麼。這是我發現的。 With pydoc鏈接:

from a import v未添加對a.v的引用。相反,當import發生時,它將b添加爲b.v的新變量,其值爲a.v。稍後更改a.v不會更改b.v的值。

Python 2

的從形式不結合模塊名稱:它通過標識符的列表,看起來它們中的每一個向上在步驟(1)中發現的模塊中,並且在結合的名稱找到對象的本地名稱空間。

Python 3

的形式從使用一個稍微複雜的過程:

  1. 發現在from子句,裝載指定,並且如果需要的話對其進行初始化的模塊;
  2. 每個在import子句指定的標識符:
    1. 檢查,如果導入的模塊有這個名字的屬性
    2. 如果沒有,嘗試導入一個子模塊具有該名稱,然後檢查導入的模塊再次針對該屬性
    3. 如果未找到該屬性,則會引發ImportError
    4. 否則,以該值的引用存儲在本地名稱空間中,在使用名稱的,就好像它是本,以其他方式使用的屬性名稱

關鍵字這裏子句在本地命名空間中爲