9
votes

Fixer de manière dynamique une méthode à un objet Python existant généré avec Swig?

Je travaille avec une classe Python, et je n'ai pas l'accès écrit à sa déclaration. Comment puis-je joindre une méthode personnalisée (telle que __ str __ ) aux objets créés à partir de cette classe sans modifier la déclaration de classe?

EDIT: Merci pour toutes vos réponses. Je les ai essayés tous mais ils n'ont pas résolu mon problème. Voici un exemple minimal que j'espère clarifiera le problème. J'utilise Swig pour envelopper une classe C ++, et le but est de remplacer la fonction __ str __ de objet retourné par le module Swig. J'utilise Cmake pour construire l'exemple:

test.py xxx

exemple.hpp xxx

exemple.cpp xxx

exemple.i xxx

cmakelists.txt xxx

pour construire et exécuter test.py, copier tout Les fichiers d'un répertoire, et dans ce répertoire exécutent xxx

Il en résulte la sortie suivante: xxx

comme vous Peut voir que l'objet Swig a sa propre fonction str , et c'est ce que j'essaie de remplacer.


1 commentaires

Autre question StackOverflow: stackoverflow.com / Questions / 972 / ...


5 Réponses :


3
votes
>>> class C(object):
...     pass
... 
>>> def spam(self):
...     return 'spam'
... 
>>> C.__str__ = spam
>>> print C()
spam
It won't work on classes which use __slots__.

1 commentaires

Malheureusement, cela ne fonctionne pas dans mon cas. La classe que j'essaie de remplacer a été autogogenerated à l'aide de Swig à partir de fichiers d'en-tête C ++.



3
votes

Créer une sous-classe. Exemple: xxx


1 commentaires

Merci pour la suggestion Alex. Il est vrai que je peux facilement créer une sous-classe, mais cela ne m'aidera pas beaucoup parce que l'objet que je travaille est retourné par une fonction que je ne puisse pas modifier. Dans le contexte de votre exemple, l'objet est de type DateTime. Je tiens à remplacer sa fonction __ str __ , afin que cela soit utile, j'ai besoin d'un moyen de lancer un objet DateTime à MyDate.



2
votes

C'est ma réponse de Une autre question : xxx


0 commentaires

1
votes

Notez que l'utilisation de la sous-classe d'Alex, vous pouvez vous aider un peu plus d'utiliser " à partir de code> ... Importer code> ... comme code> ":

>>> print datetime.now()
    'spam'


0 commentaires

23
votes

Si vous créez une classe d'emballage, cela fonctionnera avec une autre classe, soit intégrée ou non. Ceci s'appelle «confinement et délégation», et il s'agit d'une alternative commune à l'héritage:

print sds.split()
['hey', 'ho!']


7 commentaires

J'ai utilisé cette technique très tôt dans ma carrière Python pour écrire un intercepteur pour un proxy à un objet Corba distant - le client souhaitait qu'une méthode à distance particulière soit légèrement améliorée, mais sinon tout était de se comporter de la même manière. Ayant seulement récemment passé de la part de C ++, j'étais unghaste à la façon dont peu de code il a fallu pour écrire, par opposition à ce que c ++ aurait fait de moi faire.


Merci Paul! C'est exactement ce que je cherchais.


Le problème avec cette approche est que l'objet emballé résultant n'est pas capable, ce qui est parfois un gros problème


+1. J'ai été surpris que cela ait travaillé pour un objet COM. Je m'attendais à getattr échouer.


Ajout de fonctionnalités supplémentaires Ceci est communément appelé décorateur.


L'accès n'est pas toujours comme s'il s'agissait de l'objet de base. Par exemple isinstance (s, bassering == true , mais isinstance (sds, bassetruction) == false . De même, le ID () et type () Les fonctions renvoient différents résultats.


Est trop pythonique? Existe-t-il une autre suggestion pour un développeur écrit le code des coéquipiers Can-Seul-Lis-Python? Souhaite avoir d'autres ressources pour C ++ à ce terme.