types.MethodType python2中的第三个参数

时间:2018-02-18 23:11:33

标签: python python-2.7

我继承了类似这样的代码:

class A:
  def __init__(self):
    print('A')

def foo(self, *args):
  print('foo')

a = A()
setattr(a,'foo',types.MethodType(foo,a,A))

对于最后一行,我想使代码2to3兼容,但MethodType只在python3中使用两个参数。

最简单的选择可能是让它智能地破解和

try:
  setattr(a,'foo',types.MethodType(foo,a,A))
except TypeError:
  setattr(a,'foo',types.MethodType(foo,a))

但后来我意识到我不明白为什么我要在python2中添加第三个参数,因为setattr(a,'foo',types.MethodType(foo,a))适用于各种语言。

在Python2中,购买我的第三个参数是什么,将它绑定到类而不是?

>>> types.MethodType(foo,a)
<bound method ?.foo of <__main__.A instance at 0x1>>
>>> types.MethodType(foo,a,A)
<bound method A.foo of <__main__.A instance at 0x1>>

2 个答案:

答案 0 :(得分:3)

在Python 2中,方法类型构造函数的第三个参数主要用于未绑定的方法对象:

>>> class Foo(object):
...     def bar(self):
...         pass
...
>>> Foo.bar
<unbound method Foo.bar>

创建其中一个的直接构造函数调用看起来像types.MethodType(bar, None, Foo),其中bar是函数。未绑定的方法对象进行了一些类型检查,以确保它们不被用于错误类型的对象,但它们被认为不足以证明它们的存在,因此它们在Python 3中被取出。没有更多的未绑定方法对象,方法构造函数没有多大理由采取第三个参数,因此也被删除了。

答案 1 :(得分:0)

一个python2 / python3兼容的方法来实现你想要的是使用descriptor protocol (__get__)

class A(object):
  def __init__(self):
    print('A')

def foo(self, *args):
  print('foo')

a = A()
setattr(a,'foo', foo.__get__(a, A))

.__get__将返回bound method个实例