10

メタクラスを使用してクラスにインスタンス メソッドを追加するにはどうすればよいですか (はい、メタクラスを使用する必要があります)。次のような動作をしますが、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 インスタンスの 'bar' メソッドを見つけられないことです。私はそれをできた:

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

types.MethodType もありますが、それを使用するにはまだ存在しないインスタンスが必要です。ここで何か不足していますか?

4

2 に答える 2

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
于 2008-09-15T19:01:27.850 に答える
2

あなたがやりたいことはこれだと思います:

>>> 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'

これで、インスタンスが という名前のメソッドを持つFooことを期待するライブラリに s を自由に渡すことができます。Foofoobar

残念ながら、(1) メタクラスの使い方がわからず、(2) 質問を正しく読んだかどうかわかりませんが、これがお役に立てば幸いです。

func_namePython 2.4 以降でのみ割り当て可能であることに注意してください。

于 2008-09-15T18:57:29.750 に答える