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> 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'
3 Réponses :
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!')
Il est proche de ce que je veux, mais cela nécessite que je sache que le bb () code> -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.
Je ne sais pas si c'est ce que vous voulez, mais le code ci-dessous a les mêmes sorties que votre exemple: sortie: p> Vous pouvez voir que les changements dans les données intéressantes affectent les deux classes. P> P>
Également très proche, mais cela n'utilisera pas tous les attributs que class1_obj code> a. Par exemple, tenter d'appeler
new_class1_obj.name code> ne fonctionnera pas, car il n'existe que dans
class1_obj code>. 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 code>), 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 () code>.
Copier () CODE> Ne fonctionne pas, car je veux que les deux instances soient liées ensemble. Toutes les informations dans
class1_obj code> doivent être accessibles dans
new_class1_obj code>. 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 code> ressemble, de sorte que cela ne serait pas possible. Si je pouvais modifier cette classe, ce problème serait nettement plus facile à résoudre.
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: p> 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 code> pour affecter
class1_obj code>, mais je peux facilement supprimer cela en prouvant simplement
__ setattr __ () code>.
Ce qui précède s'assure également que l'ajout d'un nouvel attribut à
new_class1_obj code> n'affecte pas
class1_obj code>.
Je pourrais ajouter de la détermination de
apps code> à
__ getattribute __ code> Si je veux que le contraire fonctionne (ajout d'un nouvel attribut à
class1_obj code> affecte
new_class1_obj code>). p> h2>
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.
Dans quelles circonstances / comment est la fonction d'origine
B () code> pour
class1_obj code> 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 code> et
new_class1_obj code> simultanément. Cependant, j'exige aussi que l'original
B () code> -method peut être appelé à partir de
new_class1_obj code>. EDIT: J'ai ajouté un exemple.
Votre problème semble résulter de la méthode
BB () code> qui doit toujours appeler l'ancienne
B () code> 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 () code>. Il semble que vous devriez modéliser cela directement dans les classes.
@quamrana non, je veux que le
bb () code> -method in
new_class1_obj code> utilise le nouveau
B () code> -method, et non l'ancien . Seules les méthodes définies par
new_class1_obj code> sont autorisées à utiliser l'ancien
B () code> -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. I> 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 () code>?
@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 () code> -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.