2 votes

Monkey-Parcheando, duck-typing et argument self

Lorsque j'essaie de monkey-patch une classe avec une méthode d'une autre classe, cela ne fonctionne pas parce que l'argument self n'est pas du bon type.

Par exemple, le résultat de la méthode __str__ créée par la classe fantaisie A :

class A:
   def __init__(self, val):
       self.val=val
   def __str__(self):
       return "Fancy formatted %s"%self.val

et souhaite le réutiliser pour un cours ennuyeux B :

class B:
   def __init__(self, val):
       self.val=val

En d'autres termes :

 >>> b=B("B") 

 >>> #first try:
 >>> B.__str__=A.__str__
 >>> str(b)
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 TypeError: unbound method __str__() must be called with A instance as first argument (got nothing instead)

 >>> #second try:
 >>> B.__str__= lambda self: A.__str__(self)
 >>> str(b)
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 1, in <lambda>
 TypeError: unbound method __str__() must be called with A instance as first argument (got B instance instead)

Dans les deux cas, cela ne fonctionne pas parce que l'argument self doit être une instance de la classe A mais ce n'est manifestement pas le cas.

Ce serait bien de trouver un moyen de faire le monkey-Parcheando, mais ma question actuelle est de savoir pourquoi il est nécessaire d'avoir le paramètre implicite self pour être une instance de la "bonne" classe et ne pas dépendre uniquement du typage du canard ?

5voto

wim Points 35274

En raison de la manière dont les méthodes sont apportées aux objets de classe dans Python 2, l'objet fonction réel est caché derrière une méthode non liée, mais vous pouvez y accéder à l'aide de la fonction im_func alias __func__ attribut :

>>> B.__str__ = A.__str__.__func__
>>> str(B('stuff'))
'Fancy formatted stuff'

On peut soutenir qu'une meilleure façon d'y parvenir est d'utiliser des classes et des héritages de type nouveau.

class MyStrMixin(object):
   def __str__(self):
       return "Fancy formatted %s" % self.val

Hériter ensuite de MyStrMixin dans les deux A y B et de laisser le MRO faire son travail.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X