为了补充这里的答案,在Python 3中,最佳方法如下:
import inspect
class Test:
@staticmethod
def test(): pass
isstatic = isinstance(inspect.getattr_static(Test, "test"), staticmethod)
我们使用getattr_static
而不是getattr
,因为getattr
将检索绑定的方法或函数,而不是staticmethod
类对象。您可以对classmethod
类型和使用@property
装饰器定义的属性(例如)进行类似的检查。
请注意,即使它是staticmethod
,也不要假设它是在类内部定义的。该方法源可能来自另一个类。要获得真正的源代码,您可以查看基础函数的限定名称和模块。例如:
class A:
@staticmethod:
def test(): pass
class B: pass
B.test = inspect.getattr_static(A, "test")
print("true source: ", B.test.__qualname__)
技术上说,任何方法都可以被用作“静态”方法,只要它们被在类本身上调用,所以请记住这一点。例如,这将完美地工作:
class Test:
def test():
print("works!")
Test.test()
那个例子不能用于Test类的实例,因为该方法将绑定到实例并被称为Test.test(self)
。
在某些情况下,实例和类方法也可以用作静态方法,只要第一个参数处理得当即可。
class Test:
def test(self):
print("works!")
Test.test(None)
也许另一个罕见的情况是一个staticmethod
同时绑定到一个类或实例。例如:
class Test:
@classmethod
def test(cls): pass
Test.static_test = staticmethod(Test.test)
虽然严格来说它是一个 staticmethod
,但它的行为更像一个 classmethod
。因此,在您进行内省时,可以考虑检查 __self__
(在 __func__
上递归)以查看该方法是否绑定到类或实例。