Pergunta

Como faço para adicionar um método de instância de uma classe usando uma metaclasse (sim, eu não preciso usar uma metaclasse)?Os seguintes tipos de obras, mas o func_name ainda vai ser "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'

O meu problema é que alguns biblioteca de código, na verdade, usa o func_name e depois não consegue encontrar o 'bar' método do Foo instância.O que eu poderia fazer:

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

Há também tipos.MethodType, mas eu preciso de uma instância que faz nt existe ainda a usar esse.Estou em falta someting aqui?

Foi útil?

Solução

Tente dinamicamente, ampliando as bases de que maneira você pode aproveitar o mro e os métodos são os métodos:

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

Outras dicas

Eu acho que o que você quer fazer é isso:

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

Agora você está livre para passar Foos para uma biblioteca que espera Foo instâncias de ter um método chamado foobar.

Infelizmente, (1) não sei como usar metaclasses e (2) não sei se vou ler a sua pergunta corretamente, mas eu espero que isso ajude.

Note que func_name só é atribuível em Python 2.4 e superiores.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top