在Python 3中检测类(非实例)中的绑定方法

时间:2011-12-07 00:30:42

标签: python function methods introspection

如果某个类C包含函数或方法f,我会使用inspect.ismethod(obj.f)(其中objC的实例)来查明是否f是绑定方法还是不绑定方法。有没有办法在类级别直接执行相同的操作(不创建对象)?

inspect.ismethod不能正常工作:

class C(object):

    @staticmethod
    def st(x):
        pass

    def me(self):
        pass

obj = C()

结果(在Python 3中):

>>> inspect.ismethod(C.st) 
False
>>> inspect.ismethod(C.me)
False
>>> inspect.ismethod(obj.st) 
False
>>> inspect.ismethod(obj.me)
True

我想我需要检查函数/方法是否是类的成员而不是静态但我无法轻松完成。我想这可以使用classify_class_attrs来完成,如下所示 How would you determine where each property and method of a Python class is defined? 但我希望还有另一种更直接的方式。

3 个答案:

答案 0 :(得分:2)

Python 3中没有未绑定的方法,因此您也无法检测到它们。你所拥有的只是常规功能。最多可以看到他们是否有qualified name with a dot,表明他们是嵌套,他们的第一个参数名称是self

if '.' in method.__qualname__ and inspect.getargspec(method).args[0] == 'self':
    # regular method. *Probably*

当然,对于静态方法和碰巧有self作为第一个参数的嵌套函数,以及不使用self作为第一个参数的常规方法(在面对惯例)。

对于静态方法和类方法,您必须改为查看类字典

>>> isinstance(vars(C)['st'], staticmethod)
True

这是因为C.__dict__['st']binding to the class之前的实际staticmethod实例。

答案 1 :(得分:0)

你能使用inspect.isroutine(...)吗?和你的班级C一起运行我得到:

>>> inspect.isroutine(C.st)
True
>>> inspect.isroutine(C.me)
True
>>> inspect.isroutine(obj.st)
True
>>> inspect.isroutine(obj.me)
True

inspect.isroutine(...)的结果与inspect.ismethod(...)的结果相结合,可以让您推断出您需要知道的内容。

编辑: dm03514的回答表明您也可以尝试inspect.isfunction()

>>> inspect.isfunction(obj.me)
False
>>> inspect.isfunction(obj.st)
True
>>> inspect.isfunction(C.st)
True
>>> inspect.isfunction(C.me)
False

尽管正如Hernan所指出的那样,inspect.isfunction(...)的结果在python 3中发生了变化。

答案 2 :(得分:0)

由于对于Python 2.7中的绑定和未绑定方法,inspect.ismethod都返回True(即,已损坏),我使用:

def is_bound_method(obj):
    return hasattr(obj, '__self__') and obj.__self__ is not None

它也适用于用C实现的类的方法,例如int:

>>> a = 1
>>> is_bound_method(a.__add__)
True
>>> is_bound_method(int.__add__)
False

但在这种情况下不是很有用,因为inspect.getargspec不适用于在C中实现的函数。

is_bound_method在Python 3中保持不变,但在Python 3中,inspect.ismethod正确区分绑定和未绑定方法,因此没有必要。