如何在Python中的类实例中复制非有界方法

时间:2017-09-25 08:02:12

标签: python python-2.7 metaprogramming

我有一个代码,我想在运行时“窃取”其他类的方法。 (这是一个小游戏,我想让机器人按需改变策略。)

示例:

class X(object):
    def foo(self):
        return 1


class Y(object):
    def foo(self):
        return 2

我想'将'Y.foo'复制到X类的实例中:

x.foo = Y.foo
x.foo()  # unbound method
x.foo = types.MethodType(Y.foo, x)
x.foo()  # TypeError: unbound method foo() must be called with Y instance as first argument (got X instance instead
tmp=x.foo.__self__
x.foo=Y.foo
x.foo.__self__ = tmp  # readonly attribute
x.foo.__func__ = Y.bar.__func__ # readonly attribute

有没有办法在运行时将函数从一个类复制到另一个类,而不是:

  1. 继承(应该在instanced类的方法内完成)
  2. Y.bar
  3. 内拨打x.foo

1 个答案:

答案 0 :(得分:3)

在Python 2中,访问类上的方法会返回一个未绑定的方法。只需打开该方法即可获得原始函数,使用x.foo = types.MethodType(Y.foo.__func__, x) 属性:

x.foo = Y.foo.__func__.__get__(x)

您可以使用descriptor protocol

告诉该功能
>>> class X(object):
...     def foo(self):
...         return 1
...
>>> class Y(object):
...     def foo(self):
...         return 2
...
>>> x = X()
>>> Y.foo
<unbound method Y.foo>
>>> Y.foo.__func__
<function foo at 0x1006d1b18>
>>> Y.foo.__func__.__get__(x)
<bound method ?.foo of <__main__.X object at 0x1006e84d0>>
>>> x.foo = Y.foo.__func__.__get__(x)
>>> x.foo()
2

演示:

[Table("People")]
public class Person
{
   [Column("ID")]
   public int Id {get; set;}
}