Pregunta

¿Cómo agrego un método de instancia a una clase usando una metaclase (sí, necesito usar una metaclase)?El siguiente tipo de trabajo, pero func_name seguirá siendo "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'

Mi problema es que algún código de biblioteca en realidad usa func_name y luego no logra encontrar el método 'bar' de la instancia de Foo.Yo podría hacer:

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

También hay tipos.MethodType, pero necesito una instancia que aún no existe para usarlo.¿Me estoy perdiendo algo aquí?

¿Fue útil?

Solución

Intente extender dinámicamente las bases de esa manera podrá aprovechar el mro y los métodos son métodos reales:

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

Otros consejos

Creo que lo que quieres hacer es esto:

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

Ahora eres libre de pasar Foos a una biblioteca que espera Foo instancias para tener un método llamado foobar.

Desafortunadamente, (1) no sé cómo usar metaclases y (2) no estoy seguro de haber leído tu pregunta correctamente, pero espero que esto ayude.

Tenga en cuenta que func_name solo se puede asignar en Python 2.4 y superior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top