2014-03-13 157 views
0

類變量本質上是全局變量嗎?Python類變量的範圍?

考慮這個例子,在bar.py:

class Bar(object): 
    b = {} 

然後在foo.py:

def foo1(): 
    import bar 
    bar.Bar.b["key"] = "foo1" 


def foo2(): 
    import bar 
    print bar.Bar.b.get("key", "foo2") 

foo1() 
foo2() 

「密鑰」 值是堅持 「foo1」。

就我的目的而言,這看起來像一個全局變量。但是爲什麼在foo1和foo2的調用之間沒有重置或刪除類變量?

+0

@mgilson我在問爲什麼兩個調用之間沒有收集垃圾變量;該鏈接似乎在談論實例和類變量之間的差異。 –

回答

3

這是一個類屬性。在你的情況下,字典綁定到類Bar。每次輸入bar時,都會得到相同的類bar.Bar(畢竟它在bar的全局命名空間中),因此,您將得到相同的字典bar.Bar.b

如果希望每個Bar情況下有不同的字典,你需要做一個實例:

class Bar(object): 
    def __init__(self): 
     self.b = {} 

然後:

def foo1(): 
    import bar 
    bar.Bar().b["key"] = "foo1" 


def foo2(): 
    import bar 
    print bar.Bar().b.get("key", "foo2") 

foo1() 
foo2() 

至於爲什麼模塊bar沒有被垃圾收集,當你導入一些東西時,python存儲對該模塊的引用(參見sys.modules)。下次您導入該模塊時,python會從sys.modules中挑選適當的項目,併爲您提供參考。這有幾個原因。

  • 效率 - 爲什麼重新評估您已經評估過的代碼?
  • 理智的行爲

想象具有特殊價值的模塊:

# mod.py 
CONSTANT = object() 

現在要使用在foo.pybar.py

# bar.py 
import mod 
def bar(): 
    return mod.CONSTANT 

# foo.py 
import mod 
import bar 
if bar.bar() is mod.CONSTANT: 
    do_something() 

如果導入沒有緩存,然後mod.CONSTANT可以foo是不同的,在bar這將是非常令人吃驚的。

+0

謝謝。我擔心它被垃圾收集,因爲沒有明確的參考。 bar的全局名稱空間何時被刪除?在python關機過程中? –

+0

@ E.Beach - 啊,我現在明白你的問題了(以及本地進口功能的原因)。我編輯過 – mgilson