【问题标题】:Detecting bound method in classes (not instances) in Python 3在 Python 3 中检测类(不是实例)中的绑定方法
【发布时间】:2012-01-14 14:04:09
【问题描述】:

给定一个带有函数或方法f 的类C,我使用inspect.ismethod(obj.f)(其中objC 的一个实例)来确定f 是否是绑定方法。有没有办法在类级别直接做同样的事情(不创建对象)?

inspect.ismmethod 不能这样工作:

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? 但我希望有另一种更直接的方法。

【问题讨论】:

    标签: python function methods introspection


    【解决方案1】:

    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'] 是实际的staticmethod 实例,在binding to the class 之前。

    【讨论】:

      【解决方案2】:

      你能用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 中发生了变化。

      【讨论】:

        【解决方案3】:

        因为在 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 正确区分绑定和未绑定方法,因此没有必要。

        【讨论】:

        • 这仅对 Python two 有用,而该问题专门询问 Python three,其中没有未绑定的方法。
        猜你喜欢
        • 2020-07-17
        • 2012-02-17
        • 2011-06-08
        • 2016-11-30
        • 1970-01-01
        • 2016-06-11
        • 1970-01-01
        • 2011-04-05
        相关资源
        最近更新 更多