2017-09-25 8 views
0

実行時に他のクラスのメソッドを「盗む」コードがあります。 (これは小さなゲームなので、ボットがオンデマンドで戦略を変えることを許可したい)Pythonでクラスインスタンスにバインドされた非バインドメソッドをコピーする方法

例:

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


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

私はXクラスのインスタンスに「コピー」Y.fooしたい:

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. 継承(それがインスタンス化クラスのメソッド内で行われるべきである)
  2. Y.barからx.foo
+0

はあなたを持っています戦略パターンを見た? –

答えて

3

を呼び出します。クラスのメソッドにアクセスすると、アンバインドされたメソッドが返されます。単に__func__属性を使用して、元の関数を得るためにその方法をアンラップ:

x.foo = types.MethodType(Y.foo.__func__, x) 

あなたはdescriptor protocolを使用してバインドするためにその機能を言うことができる:

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

デモ:

>>> 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 
関連する問題