【问题标题】:How do you check whether a python method is bound or not?你如何检查一个python方法是否被绑定?
【发布时间】:2010-09-08 08:50:55
【问题描述】:

给定一个方法的引用,有没有办法检查该方法是否绑定到一个对象?你也可以访问它绑定的实例吗?

【问题讨论】:

    标签: python python-datamodel


    【解决方案1】:

    im_self attribute(仅限 Python 2)

    【讨论】:

    • 链接已损坏。
    【解决方案2】:
    def isbound(method):
        return method.im_self is not None
    
    def instance(bounded_method):
        return bounded_method.im_self
    

    User-defined methods:

    当用户定义的方法对象是 通过检索用户定义的 一个类的函数对象,它的 im_self 属性是 None 并且 方法对象被称为未绑定。 当一个是通过检索一个 用户定义的函数对象来自 类通过它的实例之一,它的 im_self 属性是实例,并且 方法对象被称为绑定。 无论哪种情况,新方法的 im_class 属性是来自的类 检索发生的位置,以及 它的im_func 属性是原始的 函数对象。

    在 Python 中 2.6 and 3.0:

    实例方法对象有新的 对象和函数的属性 包括该方法;新的同义词 对于im_self__self__im_func 也可作为__func__ 使用。老人 Python 仍然支持名称 2.6,但在 3.0 中消失了。

    【讨论】:

      【解决方案3】:

      在 python 3 中,__self__ 属性设置在绑定方法上。在普通函数(或未绑定的方法,它们只是 python 3 中的普通函数)上,它没有设置为 None

      使用这样的东西:

      def is_bound(m):
          return hasattr(m, '__self__')
      

      【讨论】:

        【解决方案4】:

        所选答案几乎在所有情况下都有效。但是,当使用选择的答案检查方法是否绑定在装饰器中时,检查将失败。考虑这个示例装饰器和方法:

        def my_decorator(*decorator_args, **decorator_kwargs):
            def decorate(f):
                print(hasattr(f, '__self__'))
                @wraps(f)
                def wrap(*args, **kwargs):
                    return f(*args, **kwargs)
                return wrap
            return decorate
        
        class test_class(object):
            @my_decorator()
            def test_method(self, *some_params):
                pass
        

        装饰器中的print 语句将打印False。 在这种情况下,我找不到任何其他方法,只能使用参数名称检查函数参数并查找名为 self 的函数参数。这也保证可以完美地工作,因为方法的第一个参数没有被强制命名为 self 并且可以具有任何其他名称。

        import inspect
        
        def is_bounded(function):
            params = inspect.signature(function).parameters
            return params.get('self', None) is not None
        

        【讨论】:

        • 好吧,f 从来没有真正绑定到test_class,这就是这里的复杂性。甚至decorate 也没有绑定(您可以通过检查 test_class.test_method != decorate 来验证)。绑定方法是从 decorate 创建的,而 that 是附加到 test_class 的内容。您真正要查找的是是否已从特定函数创建了绑定方法。我不确定这是否可能
        • 我认为这是知道给定函数是否期望接收实例的唯一方法。
        • 进口检查; expectself = next(iter(inspect.signature(function))) == 'self'
        【解决方案5】:

        同时适用于 Python 2 和 3 的解决方案很棘手。

        使用包six,一种解决方案可能是:

        def is_bound_method(f):
            """Whether f is a bound method"""
            try:
                return six.get_method_self(f) is not None
            except AttributeError:
                return False
        

        在 Python 2 中:

        • 常规函数没有im_self 属性,因此six.get_method_self() 将引发AttributeError,这将返回False
        • 未绑定的方法会将im_self 属性设置为None,因此这将返回False
        • 绑定方法会将im_self 属性设置为非None,因此这将返回True

        在 Python 3 中:

        • 常规函数没有__self__ 属性,因此six.get_method_self() 将引发AttributeError,这将返回False
        • 未绑定的方法与常规函数相同,因此将返回 False
        • 绑定方法将设置__self__ 属性(设置为非None),因此这将返回True

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-27
          • 2017-11-16
          • 2015-08-30
          • 2018-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-29
          相关资源
          最近更新 更多