-1
votes

Comment remplacer une méthode d'instance par exemple dans Python sans le remplacer?

Description

Ma question est très similaire à la question soulevée ici , avec une différence: je ne veux pas directement éditer ou remplacer quelque chose dans l'instance de classe d'origine. P>

Donc, essentiellement, imaginez que nous avons une classe définie comme p> xxx pré>

maintenant ce que je veux faire Créez une fonction que l'utilisateur peut appeler, où cela me fournit une instance de Classe1 code> (ou toute sous-classe dérivée). Ensuite, je retourne un objet qui se comporte exactement identique à l'instance fournie, sauf que le B () code> -metthod a été remplacé par P>

# Use with expected outputs
>>> class1_obj = Class1('TEST')
>>> new_class1_obj = get_new_Class1_obj(class1_obj)
>>> class1_obj is new_class1_obj
False
>>> class1_obj.name
'TEST'
>>> class1_obj.a()
"This is the Class1 a()-method!"
>>> class1_obj.b()
"This is the Class1 b()-method!"
>>> class1_obj.bb()
"This is the Class1 b()-method!"
>>> new_class1_obj.name
'TEST'
>>> new_class1_obj.a()
"This is the Class1 a()-method!"
>>> new_class1_obj.b()
("This is the Class1 b()-method!", "This is the new Class1 b()-method!")
>>> new_class1_obj.bb()
("This is the Class1 b()-method!", "This is the new Class1 b()-method!")
>>> class1_obj.name = 'TEST2'
>>> class1_obj.name
'TEST2'
>>> new_class1_obj.name
'TEST2'


9 commentaires

Dans quelles circonstances / comment est la fonction d'origine B () pour class1_obj appelé? Peut-être que cela nous donnerait une idée sur la façon de procéder


Eh bien, si, par exemple, l'utilisateur souhaite utiliser les deux class1_obj et new_class1_obj simultanément. Cependant, j'exige aussi que l'original B () -method peut être appelé à partir de new_class1_obj . EDIT: J'ai ajouté un exemple.


Votre problème semble résulter de la méthode BB () qui doit toujours appeler l'ancienne B () méthode si dans l'instance d'origine ou dans la nouvelle instance, mais tout appelant extérieur Sur la nouvelle instance serait redirigé vers le nouveau B () . Il semble que vous devriez modéliser cela directement dans les classes.


@quamrana non, je veux que le bb () -method in new_class1_obj utilise le nouveau B () -method, et non l'ancien . Seules les méthodes définies par new_class1_obj sont autorisées à utiliser l'ancien B () -method.


J'ai une instance et je souhaite mettre à jour l'une de ses méthodes d'instance avec une nouvelle, sans modifier l'instance originale. Il y a une contradiction. Mise à jour des méthodes d'instance signifie modifier l'instance.


Vous devez être clair. Quels sont les instances (anciennes et nouvelles) peuvent utiliser les méthodes anciennes et nouvelles B () ?


@quamrana il n'est pas spécifique d'instance, mais spécifique à la méthode. Seules ces méthodes remplacées / remplacées sont autorisées à utiliser l'ancien B () -method. Toutes les méthodes peuvent utiliser le nouveau.


Je suis encore confus. Vous devez fournir un exemple d'utilisation: instanciez l'original et utilisez-le. Créez une nouvelle instance modifiée. Utilisez à nouveau l'instance originale et nouvelle instance pour voir les différences entre la manière dont l'original a commencé et comment l'original se comporte maintenant et la nouvelle instance se comporte.


@quamrana j'ai ajouté un exemple avec des sorties attendues.


3 Réponses :


0
votes

Je ne suis pas absolument sûr de ce que vous voulez, mais cela peut-il être approprié? (File test.py Testé OK avec Python 3.7.3)

$ python test.py
are insts same?  False
class1_obj.name? TEST
class1_obj.a(): This is the Class1 a()-method!
class1_obj.b(): This is the Class1 b()-method!
class1_obj.bb(): This is the Class1 b()-method!
new_class1_obj.name? TEST
new_class1_obj.a(): This is the Class1 a()-method!
new_class1_obj.b(): ('This is the Class1 b()-method!', 'This is the new Class1 b()-method!')
new_class1_obj.bb(): ('This is the Class1 b()-method!', 'This is the new Class1 b()-method!')


4 commentaires

Il est proche de ce que je veux, mais cela nécessite que je sache que le bb () -method existe. Comme je n'ai pas cette connaissance à tout moment (comme indiqué dans mon post), je ne peux mal que je ne peux pas le faire de cette façon.


J'ai examiné ma réponse, il me semble que cette fois pour être proche de votre exemple ci-dessus. Qu'est-ce que tu en penses?


Remarque: la réponse mise à jour de @quamrana, ci-dessus, est meilleure que la mienne si vous avez besoin d'un cyclot


Merci de votre réponse, mais cela nécessite de réinitialiser l'instance tout ce que je ne veux pas. Les anciens et nouveaux instances doivent toujours être liés les uns aux autres.



0
votes

Je ne sais pas si c'est ce que vous voulez, mais le code ci-dessous a les mêmes sorties que votre exemple: xxx

sortie: xxx

Vous pouvez voir que les changements dans les données intéressantes affectent les deux classes.


6 commentaires

Également très proche, mais cela n'utilisera pas tous les attributs que class1_obj a. Par exemple, tenter d'appeler new_class1_obj.name ne fonctionnera pas, car il n'existe que dans class1_obj . Je vais ajouter cela à l'exemple.


Une idée intéressante, mais le problème ici est que faire une copie profonde de l'instance que je vais utiliser ici ( mpi4py.mpi.intracomm ), n'est pas possible. Faire une copie signifierait également la réinitialisation de tout, ce qui signifie que les modifications apportées aux attributs de l'ancienne instance n'est pas mise à jour dans le nouveau. Vous comprenez quelle situation je me trouve? :)


Alors peut-être que vous avez juste besoin d'un copier () .


Copier () Ne fonctionne pas, car je veux que les deux instances soient liées ensemble. Toutes les informations dans class1_obj doivent être accessibles dans new_class1_obj . Cela inclut les modifications apportées.


Mis à jour avec une nouvelle idée de déplacer toutes les données intéressantes dans un autre objet.


Je n'ai aucun contrôle sur ce que classe1 ressemble, de sorte que cela ne serait pas possible. Si je pouvais modifier cette classe, ce problème serait nettement plus facile à résoudre.



0
votes

solution possible

Après avoir regardé la réponse donnée par Quamrana , j'ai proposé une solution possible à cette , mais je voudrais des commentaires sur celui-ci: xxx xxx

toutes les sorties ici sont les sorties que je veux. Je ne sais toujours pas si je veux des changements non-méthodes dans new_class1_obj pour affecter class1_obj , mais je peux facilement supprimer cela en prouvant simplement __ setattr __ () . Ce qui précède s'assure également que l'ajout d'un nouvel attribut à new_class1_obj n'affecte pas class1_obj . Je pourrais ajouter de la détermination de apps à __ getattribute __ Si je veux que le contraire fonctionne (ajout d'un nouvel attribut à class1_obj affecte new_class1_obj ).


1 commentaires

Oui, c'est une bonne idée: vous faites votre nouvelle classe suivez toutes les non-méthodes de l'ancienne classe, même de nouveaux attributs pouvant être ajoutés plus tard.