2016-03-08 106 views
0

在python 2.7中,我想創建一個靜態變量來存儲運行封閉類的靜態方法的結果。參考靜態變量的靜態方法

我試過如下:

class A: 
    @staticmethod 
    def foo(): 
      return 1 
    v = A.foo() # a static variable 
print A.v 

返回錯誤:

NameError: name 'A' is not defined 

然而,參考其他類的靜態變量的作品:

class B: 
    @staticmethod 
    def foo(): 
      return 1 
class A: 
    @staticmethod 
    def foo(): 
      return 1 
    v = B.foo() 

print A.v 

>>> 1 

任何解釋嗎?

編輯:

用例的這個場景是緩存foo的結果,並且在A的名字空間括起來。 接下來的答案我明白,A尚未定義在執行時,這會導致錯誤。 我想出了以下延遲計算:

class A: 
    @staticmethod 
    def foo(): 
      print 'running foo' 
      return 1 

    @staticmethod 
    def get_v(): 
      try: 
        return A.v 
      except AttributeError: 
        A.v = A.foo() 
        return A.v 

print A.get_v() 
print A.get_v() 

>>> running foo 
>>> 1 
>>> 1 

這似乎做的工作,但稍顯麻煩。

+2

那時'A'甚至不存在,因此錯誤。 –

+0

你能解釋一下你爲什麼要這樣做嗎?僅僅是爲了緩存目的? –

+0

在這個例子中,你會想把'foo()'移到類的外面並使之成爲一個函數,但是我懷疑你想做更復雜的事情。 – BlueTrin

回答

3

使用@classmethod,並緩存類對象的值。

class S(object): 
    @classmethod 
    def f(klass): 
     if not hasattr(klass, '_f'): 
      print "Calculating value" 
      klass._f = 5 

     return klass._f 

當來自不同的實例調用兩次:

>>> s = S() 
>>> s2 = S() 
>>> s.f() 
Calculating value 
5 
>>> s2.f() 
5 

值共享超過S所有實例。

1

除了想知道爲什麼你這樣做:在一次分配v(在該行v = A.foo()A尚未定義(的A的定義是整個class塊,所以A ISN」。 T標準,直到該塊後)

在你的第二個例子,B當你說v = B.foo()已經被定義

編輯:。令我百思不解的是:

class A: 
    @staticmethod 
    def foo(): 
     return 1 
    v = foo() 

運行在

v = foo() 
TypeError: 'staticmethod' object is not callable 
+0

我想緩存foo的返回值只運行一次,並在A的用戶之間共享。您可以提供另一種方式嗎? – Gabis

+1

將函數移到'A'的定義之前,並在'A'內設置'v = foo()'。 – acdr

+1

或者,如果你想在'A'(作爲一個靜態方法)中保留函數,在'A'完全定義之後,寫'A.v = A.foo()'。 – acdr

1

此代碼的結果不能調用從類A中的(靜態的)方法,直到類完全定義(塊結束class)。但是你可以儘快類的定義定義一個靜態變量:

class A: 
    @staticmethod 
    def foo(): 
     print "running foo" 
     return 1 
A.v = A.foo() 

然後,您可以在任何地方使用

print A.v 
+0

你知道爲什麼直到'A'被完全定義之後才能調用'foo'嗎?如果'A類:; foo = lambda:1; v = foo()'是允許的,爲什麼不'def foo():return 1'而不是'foo = lambda:1'? – acdr

+1

@acdr在你的例子中,你賦值給靜態變量,給一個變量賦一個* external *函數,並通過靜態變量調用* external *函數。它和'def foo():相同。返回1; A類:f = foo; v = f()'。但是一個* static *方法屬於一個類,並且在類完全定義之前不能被執行。 –