2008-09-15 11 views
8

メタクラスを使用してクラスにインスタンスメソッドを追加するにはどうしたらいいですか(はい、メタクラスを使用する必要があります)?次の作品のようなものが、FUNC_NAMEはまだ「foo」というようになります。メタクラスを使用してメソッドを追加する方法

def bar(self): 
    print "bar" 

class MetaFoo(type): 
    def __new__(cls, name, bases, dict): 
     dict["foobar"] = bar 
     return type(name, bases, dict) 

class Foo(object): 
    __metaclass__ = MetaFoo 

>>> f = Foo() 
>>> f.foobar() 
bar 
>>> f.foobar.func_name 
'bar' 

私の問題は、いくつかのライブラリコードが実際にFUNC_NAMEを使用し、後でFooのインスタンスの「バー」の方法を見つけることができないということです。私は何ができる:

dict["foobar"] = types.FunctionType(bar.func_code, {}, "foobar") 

はtypes.MethodTypeもありますが、私はそれを使用するためにはまだ存在してdoes'ntインスタンスを必要としています。私はここでsometing行方不明ですか?

+0

なぜあなたは、メソッドの名前を変更しようとしていますか? do [bar.func_name] = barはあなたが望むものを達成できないのですか? –

+0

良い質問...私は当初、dictで定義された属性に基づいてメソッド名を作成していましたが、メソッドの実装が同一であれば無意味です。 –

答えて

15

動的にあなたがMROの利点を取ることができ、方法は、実際のメソッドでそのように拠点を拡張してみてください。

class Parent(object): 
    def bar(self): 
     print "bar" 

class MetaFoo(type): 
    def __new__(cls, name, bases, dict): 
     return type(name, (Parent,) + bases, dict) 

class Foo(object): 
    __metaclass__ = MetaFoo 

if __name__ == "__main__": 
    f = Foo() 
    f.bar() 
    print f.bar.func_name 
+2

'bar'実装を参照するいくつかのメソッドを作成したいのですが? –

+0

こんにちはAaron、それは正常に動作しますが、Fooから継承する新しいクラスNewFooを作成しようとすると、MROの問題により継承エラーが発生します。 私は同様のアプローチでこの問題を解決しようとしました:https://github.com/tierratelematics/pypom_form/blob/refactor/pypom_form/meta.py#L111しかし、それが最良のアプローチかどうかわかりませんそれを行うためのより無邪気な方法があります。 Python 3でもうまく動作するはずです –

2

私は何がやりたいことは、このだと思う:今、あなたはFooインスタンスがfoobarという名前のメソッドを持っていることを期待図書館にFoo Sを渡すことは自由です

>>> class Foo(): 
... def __init__(self, x): 
...  self.x = x 
... 
>>> def bar(self): 
... print 'bar:', self.x 
... 
>>> bar.func_name = 'foobar' 
>>> Foo.foobar = bar 
>>> f = Foo(12) 
>>> f.foobar() 
bar: 12 
>>> f.foobar.func_name 
'foobar' 

残念ながら、(1)メタクラスの使い方がわかりません。(2)あなたの質問を正しく読んでいないと思いますが、これが役立つことを願っています。

func_nameは、Python 2.4以降でのみ割り当て可能です。

関連する問題