2011-12-14 203 views
5

我想將類的一些信息存儲爲類(靜態)變量。但是,我無法弄清楚這些東西是如何初始化的。這是一個基本的,愚蠢的例子:Python類變量初始化

class A(object): 
    clsVar = 'a' 
    @classmethod 
    def clsMeth(cls): 
     print 'changing clsVar' 
     cls.clsVar = 'b' 
    A.clsMeth() 
# prints 'changing clsVar' 

print A.clsVar # prints 'a' 
A.clsVar = 'b' 
print A.clsVar # prints 'b' 

由於函數得到調用(print語句的工作),爲什麼沒有類變量逗留變化?如果我不想在類定義完成後再使用它,我必須使用元類嗎?

[具體來說,我想要clsMeth是一個裝飾器,並且讓類變量成爲所有裝飾過的函數的列表。我猜這是不正確的方式去完成,所以我已經走了,但我仍然好奇。]

編輯:許多人指出,上面的代碼贏得'運行。我在IPython會話中運行它,其中A.clsMeth()的調用將引用A的先前版本並運行。我想,這就是使用解釋型語言的風險。我結束了這樣的打算:

outsideDict = {} 
def outsideDec(func): 
    outsideDict[func.__name__] = func 

class A(object): 
    @outsideDec 
    def someMethod(self): 
     print 'ID %s' % id(self) 

    def otherMethod(self): 
     print 'other' 

print outsideDict 
one, two = A(), A() 
outsideDict['someMethod'](one) 
outsideDict['someMethod'](two) 

或許,這應該是一個問題,但是當outsideDec獲取運行,有沒有辦法告訴它就是類的說法是會員嗎?或者有沒有更好的方式在Python中做這樣的內省?我承認我在這裏轉向課程,所以我會接受下面的答案並做更多的研究。感謝大家!

+0

我得到的是調用`A.clsMeth`時發生錯誤,因爲`A`未定義。也許你在使用解釋器,並且你有一箇舊的`A`定義? – jcollado 2011-12-14 18:45:51

+0

你如何運行這個示例?這不能工作,因爲語法不正確。 `A.clsMth()`不能像這樣放在類定義中。 – gecco 2011-12-14 18:47:28

回答

4

A定義將不會運行到A.clsMeth()的調用,爲A不會在這一點上存在:

>>> class A(object): 
...  clsVar = 'a' 
...  @classmethod 
...  def clsMeth(cls): 
...   print 'changing clsVar' 
...   cls.clsVar = 'b' 
...  A.clsMeth() 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 7, in A 
NameError: name 'A' is not defined 

該代碼可能已經似乎工作,如果A先前已被定義(例如,如果你正在REPL中測試它),但是A.clsMeth的調用可能會被舊的類調用,這將會被新類調用。

但是,我們絕對可以把該呼叫的定義後,並得到你想要的結果:

>>> class A(object): 
...  clsVar = 'a' 
...  @classmethod 
...  def clsMeth(cls): 
...   print 'changing clsVar' 
...   cls.clsVar = 'b' 
... 
>>> A.clsMeth() 
changing clsVar 
>>> A.clsVar 
'b' 

當然,作爲fabianhrj指出,你可以把它在構造函數中一樣好,但它贏得了」直到你創建一個實例纔會被調用。

0

你需要把所有的語句放在一個函數中才能工作。我建議如果你想在創建對象時運行某些東西,只需將它放在構造函數中即可。

class A: 
    def clsMeth(self): 
     print("Changing clsVar") 
     self.clsVar = 'b' 
    def __init__(self): 
     self.clsMeth() 
    clsVar = 'a' 

我們在那裏。