Je travaille avec une bibliothèque tierce qui a une mauvaise repr pour une classe et je voudrais l'écraser une fois qu'une instance de cette classe a été créée.
J'ai vu comment créer des méthodes liées dans un objet existant.
class toy(): pass inst= toy() class inhtoy(): def __new__(cls,obj): def __repr__(self): return 'Sucessful' import types obj.__repr__ = types.MethodType(__repr__,obj) return obj t = inhtoy(inst)
En effet, si j'appelle t. repr () ça marche, cependant ça n'écrase pas l'original repr . Il apparaît comme
une sorte de méthode locale.
L'appel de repr (t)
pointe toujours vers la représentation d'origine '<__ main __. toy object at>'
mais pas celle écrasée.
Y a-t-il un moyen de le faire correctement?
Merci
3 Réponses :
après quelques recherches, j'ai trouvé cette réponse. la façon de le faire est sur une instance en direct est:
t.__class__.__repr__ = my_custom_repr
veuillez noter que cela change toutes les instances de classe et pas seulement cette instance
p >
Eh bien, dans mon but, cela fonctionnera. Savez-vous pourquoi cela fonctionne de cette façon?
malheureusement non, mais si vous le comprenez, je serais heureux si vous me le faites savoir
@Nullman J'ai ajouté une réponse pour tenter d'expliquer pourquoi vos solutions fonctionnent et que l'OP ne fonctionne pas; au cas où vous seriez toujours intéressé ...
Vous pouvez utiliser l'héritage pour créer une nouvelle classe dérivée de la classe d'intérêt, puis remplacer la méthode repr
class inhtoy(toy): def __init__(self): toy.__init__(self) def __repr__(self): # Your repr method
La réponse de
@ Nullman fonctionne, car leur solution est en fait de changer l'objet de classe toy
, dont t
est une instance, pas l'instance elle-même, comme le fait votre approche.
L'attribut spécial __class__
a> fait référence à l'objet de classe auquel appartient une instance.
def __repr__(self): return "Success" inst.__repr__ = types.MethodType(__repr__, obj)
Ainsi, t .__ class __.__ repr__ = my_custom_repr
assigne à __repr __ code> sur la classe
toy
, pas sur l'instance t
.
Ceci devient visible lors de la comparaison de la sortie de print (t .__ repr__ )
entre votre approche et celle de Nullman. En supposant qu'une fonction au niveau du module __repr__
ressemble à ceci:
<bound method inhtoy.__new__.<locals>.__repr__ of <__main__.toy object at 0x7f76e0b61f98>>
Votre solution montre:
<bound method __repr__ of <class '__main__.toy'>>
Remarque, il dit __main __. objet jouet
.
La solution de Nullman l'affiche comme:
<bound method __repr__ of <__main__.toy object at 0x00000000029E5A90>>
Lorsque vous appelez t .__ repr __ ()
en utilisant votre approche, vous appelez la méthode que vous avez définie sur l'instance t
, donc elle renvoie ce que vous lui avez fait relancer; la chaîne Success
dans votre exemple.
Lors de l'utilisation de repr ()
, cependant, la classe définit la sortie:
Une classe peut contrôler ce que cette fonction renvoie pour ses instances en définir une méthode
__repr __ ()
.
Comme Nullman l'a souligné à juste titre, leur approche modifiera le comportement de tous les objets et futurs existants, instanciés à partir de toy
.
En ce qui concerne le nom étrange, que la méthode assignée montre lors de l'utilisation de votre code:
def __repr__(self): return repr(self.__class__)
... c'est la fonction nom qualifié provenant du __qualname__
attribut spécial. C'est la fonction __repr__
de la portée locale de la méthode __new__
de votre classe inhtoy
.
En parlant de cela, passer votre instance inst
via la méthode magique __new__
de votre classe inhtoy
ne permet pas vraiment de faire grand-chose. Votre code est fonctionnellement équivalent à:
print(t.__class__ is toy) # True
Aussi mauvais que soit leur
__repr__
, le remplacer par un substitut de votre choix sera encore plus déroutant.alors que je voudrais également savoir comment faire cela à une instance en direct, pourquoi ne pas sous-classer leur classe et simplement changer le
__repr__
?@Nullman Parce que le sous-classement obligerait l'utilisateur à en hériter. Cela changerait également le nom de la classe générant des incompatibilités avec la bibliothèque tierce. La modification de l'objet conserve tout le même.