2013-01-06 65 views
5

Simmilar問題(與Python2相關:Python: check if method is staticPython3:檢查方法是靜態

讓海外商品會有下面的類定義:

class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 

在Python 3沒有instancemethod了,一切功能,所以與Python 2相關的答案將不再適用。

正如我所說,一切都是功能,所以我們可以打電話A.f(0),但我們當然不能打電話給A.f()(參數錯配)。但是,如果我們創建一個實例a=A(),並且我們將其稱爲a.f() Python將作爲第一個參數傳遞給函數A.fself。調用a.g()可以防止發送它或捕獲self - 因此必須有方法來測試這是否是靜態方法。

那麼我們可以在Python3中檢查一個方法是否被聲明爲static

+0

我能問你爲什麼要做這個答案下面? –

+1

當然,我正在做我自己的插件框架,我想檢查一些接口聲明,我很想知道是否有聲明爲staticmethod或不:) :) –

回答

8
class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 
print(type(A.__dict__['g'])) 
print(type(A.g)) 

<class 'staticmethod'> 
<class 'function'> 
+0

太棒了!你能否解釋一下爲什麼'A .__ dict __ ['g']'給出的不是'A.g'? –

+5

'A .__ dict __ ['g']'與A.g'不同,因爲函數是[描述符](http://docs.python.org/2/reference/datamodel.html#descriptors)。函數對象是描述符,因爲它們定義了一個'__get__'方法,當使用點符號訪問對象時(如'A.f'),該方法被magic調用。描述符協議是(例如)在實例上調用_function_時如何轉換爲_bound method_。瀏覽'__dict__',而不是使用點符號,繞過描述符協議。 –

1

我需要這個解決方案,並寫下了基於從@root

def is_method_static(cls, method_name): 
    # http://stackoverflow.com/questions/14187973/python3-check-if-method-is-static 
    for c in cls.mro(): 
     if method_name in c.__dict__: 
      return isinstance(c.__dict__[method_name], staticmethod) 
    raise RuntimeError("Unable to find %s in %s" % (method_name, cls.__name__)) 
+0

這隻適用於未繼承的靜態方法。如果你想支持繼承的靜態方法,你可以使用'inspect.getattr_static'而不是直接訪問'__dict__'。 –

+0

謝謝,getattr_static在3.2中是新的。我的代碼在Python2和Python3中運行 –