2010-09-18 4 views
4

Avoir un objet x qui est une instance de une classe comment créer une nouvelle instance de la même classe que l'objet x, sans importer que toutes les possibles des classes dans le même espace dans lequel nous voulons créer une nouvelle objet du même type et en utilisant isinstance pour déterminer le type correct.Comment créer une nouvelle instance de la même classe que l'autre objet?

Par exemple, si x est un nombre décimal:

>>> from decimal import Decimal 
>>> x = Decimal('3') 
>>> x 
Decimal('3') 

comment créer nouvelle instance de Decimal. Je pense que la chose évidente à faire serait l'une de ces:

>>> type(x)('22') 
Decimal('22') 
>>> x.__class__('22') 
Decimal('22') 

Depuis __class__ ne fonctionnera pas sur int par exemple:

>>> 1.__class__ 
    File "<stdin>", line 1 
    1.__class__ 

Est-il une bonne pratique d'utiliser type pour y parvenir, ou est y a-t-il d'autres façons ou d'autres mises en garde lorsque vous utilisez cette approche pour créer de nouveaux objets?

Remarque: Il y avait une réponse qui est maintenant supprimé qui a donné une bonne façon d'obtenir __class__ de int.

>>> (1).__class__ 
<type 'int'> 

Cas d'utilisation

La question est surtout théorique, mais je me sers de cette approche en ce moment avec Qt pour créer de nouvelles instances de QEvent. Par exemple, puisque les objets QEvent sont consommés par le gestionnaire d'événements d'application afin de publier l'événement sur QStateMachine, vous devez créer une nouvelle instance de l'événement sinon vous obtenez une erreur d'exécution car l'objet C++ sous-jacent est supprimé. Et comme j'utilise des sous-classes personnalisées QEvent qui partagent toutes la même classe de base, les objets acceptent le même ensemble d'arguments prédéfini.

Répondre

6

L'appel type(x) est certainement la manière canonique de créer une nouvelle instance de exactement le même type que x. Cependant, les arguments à passer à cet appel ne sont pas donnés, car la "signature" (nombre et types d'arguments à transmettre dans l'appel) change avec chaque type différent; donc, si vous n'avez aucune idée de ce que le type pourrait être, vous avez besoin de plus d'introspection à cet effet (ainsi qu'une règle ou une heuristique sur ce que tous les arguments que vous voulez passer une fois que vous avez déterminé, par exemple, n'importe quel nombre de 0 à 3, et que les noms optionnels/mots-clés d'argument sont 'y', 'z', 't' ... évidemment il est impossible d'établir une règle générale ici!). Alors, pouvez-vous clarifier (une fois que le type à instancier est, facilement, déterminé ;-) comment vous allez aborder les parties difficiles de votre problème, que vous ne mentionnez même pas? Quelles contraintes pouvez-vous assumer sur la signature du type? Avez-vous besoin d'effectuer des vérifications de santé mentale ou est-ce OK pour provoquer un TypeError en appelant avec le mauvais type ou le nombre d'arguments? Etc...sans plus d'informations de cette nature, votre question ne se prête pas à prouver une réponse qui peut effectivement être utilisé dans le monde réel! -)

Questions connexes