在Python中,我需要高效且通用地测试类的属性是否是实例方法。调用的输入将是要检查的属性的名称(字符串)和对象。
无论属性是否为实例方法,hasattr都返回true。
有什么建议吗?
例如:
class Test(object):
testdata = 123
def testmethod(self):
pass
test = Test()
print ismethod(test, 'testdata') # Should return false
print ismethod(test, 'testmethod') # Should return true
答案 0 :(得分:12)
def hasmethod(obj, name):
return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
答案 1 :(得分:4)
import types
print isinstance(getattr(your_object, "your_attribute"), types.MethodType)
答案 2 :(得分:3)
您可以使用inspect
模块:
class A(object):
def method_name(self):
pass
import inspect
print inspect.ismethod(getattr(A, 'method_name')) # prints True
a = A()
print inspect.ismethod(getattr(a, 'method_name')) # prints True
答案 3 :(得分:2)
此函数检查属性是否存在,然后检查属性是否是使用inspect
模块的方法。
import inspect
def ismethod(obj, name):
if hasattr(obj, name):
if inspect.ismethod(getattr(obj, name)):
return True
return False
class Foo:
x = 0
def bar(self):
pass
foo = Foo()
print ismethod(foo, "spam")
print ismethod(foo, "x")
print ismethod(foo, "bar")
答案 4 :(得分:0)
请注意,@classmethod
修饰的函数将通过其他答案中的所有测试。您是否希望将这些视为“实例方法”?也许这只是语义,但根据定义,它们对类进行操作,而不是生成的实例。我不确定 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__
不是类分别排除了非函数属性和类方法。