Question

Comment puis-je ajouter une méthode d'instance à une classe à l'aide d'une métaclasse (oui, il faut utiliser une métaclasse)? Le type de travail suivant fonctionne, mais le func_name sera toujours "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'

Mon problème est que certains codes de bibliothèque utilisent réellement le nom_fonction et que plus tard, la méthode 'bar' de l'instance Foo n'a pas été trouvée. Je pourrais faire:

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

Il existe également des types.MethodType, mais j'ai besoin d'une instance qui n'existe pas encore pour l'utiliser. Est-ce qu'il me manque quelque chose ici?

Était-ce utile?

La solution

Essayez d'étendre dynamiquement les bases de cette façon, vous pouvez tirer parti de la méthode mro et les méthodes sont des méthodes réelles:

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

Autres conseils

Je pense que ce que vous voulez faire est le suivant:

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

Vous êtes maintenant libre de passer des Foo à une bibliothèque qui s'attend à ce que les instances Foo aient une méthode nommée foobar .

Malheureusement, (1) je ne sais pas comment utiliser les métaclasses et (2) je ne suis pas sûr de lire votre question correctement, mais j'espère que cela vous aidera.

Notez que nom_fonction est uniquement assignable dans Python 2.4 et versions ultérieures.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top