如何测试类属性是否为实例方法

时间:2009-07-07 09:23:24

标签: python methods attributes instance

在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

5 个答案:

答案 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__ 不是类分别排除了非函数属性和类方法。

相关问题