请注意@classmethod
-decorated 函数将通过其他答案中的所有测试。您希望这些被视为“实例方法”吗?也许这只是语义,但根据定义,它们对类进行操作,而不是生成的实例。我不确定 hasmethod2 (我提出的解决方案)失败的情况,但至少它可以警惕类方法:
import inspect
import types
def hasmethod(obj, name):
return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
def hasmethod2(obj, name):
try:
attr = getattr(obj, name)
return not inspect.isclass(attr.__self__)
except AttributeError:
return False
class Test(object):
testdata = 123
def testmethod(self):
pass
@classmethod
def testmethod2(cls):
pass
# Returns True. This may be undesired depending on your definition of 'instance method'
hasmethod(Test(), 'testmethod2')
# Returns False
hasmethod2(Test(), 'testmethod2')
它之所以有效,__self__
是因为绑定到主要调用参数(类方法的类实例,普通属性的对象实例,模块或各种内置函数的任何内容)。因此,检查类的存在__self__
和__self__
非类分别排除了非函数属性和类方法。