2016-08-05 55 views
4

最近我設置了這個例子,並且對結果感到驚訝。我將與代碼演示了這一點:Python多模塊全局變量。 Python中的錯誤?

文件1:b.py

delta = 0.0 

def example(): 
    global delta 

    delta = 1 

def ret_delta(): 
    return delta 

文件2:a.py

from b import * 

example() 

#WHY ARE THESE DIFFERENT? 
print(delta) # prints: 0.0 
print(ret_delta()) # prints: 1 

這是沒有意義的!爲什麼要訪問變量並調用返回該變量的函數會有什麼不同?

爲了您在Windows 32位

+0

'from b import *'是不好的形式(並且模糊在這種情況下發生的事情是其中一個原因)。考慮'輸入b'並使用'b.delta'來代替。這是更明確的,_and_將實際上按照您的預期工作。 – marcelm

回答

5

當你做參考,我使用Python 3.5.2

from b import *

a.py

,它進口的模塊b中定義的所有名稱(包括delta)進入a的名字空間。由於Python中不可變類型的float,您可以考慮a.deltab.delta完全分離的變量,指向不同的值。 因此,第一個print()打印的初始值爲a.delta,而第二個打印的更新值爲b.delta

+0

謝謝,這似乎解釋它! –

2

from b import *在您的a模塊全局變量中創建一系列新的引用。這些副本中的每一個都從b名稱中複製參考。然而它們是獨立的全局變量。

請記住,在Python中,名稱只是標籤;他們被綁在物體上。您可以通過賦值創建該關係,並且可以爲每個對象創建多個標籤。這就是發生在這裏的事情,您在b中標註標籤,在a中標註標籤,在from b import *之後,兩個模塊中的標籤都指向相同的對象。

但是,您隨後將不同對象分配給b中的delta名稱。現在,該標籤不再引用舊的浮動對象0.0。但是你沒有改變a中的delta標籤與什麼關聯。

如果您要將名稱作爲模塊名稱的前綴,您將獲得a.deltab.delta;分配b.delta = 1不會改變a.delta,他們住在不同的命名空間。

您可能想了解Python名稱的工作方式;看到Ned Batchelder出色的Facts and myths about Python names and values presentation

+0

你的條款在答覆混淆了我。在|中,從b導入a後,它們引用相同的對象|,從b導入a?是對的嗎? –

+0

@EkeymeMo:我不確定我是否按照你的評論,對不起。 –

+0

對不起,我之前的評論是在手機上寫的,我不能插入高亮特徵。在你的答案中,你說'從b導入後,他們指的是相同的對象',我想你想說的是'...從b導入* ...'。是對的嗎? –