127 votes

Copie du constructeur en python ?

Existe-t-il un constructeur de copie en python ? Si non, que dois-je faire pour réaliser quelque chose de similaire ?

J'utilise une bibliothèque et j'ai ajouté une fonctionnalité supplémentaire à l'une des classes qu'elle contient. Je veux pouvoir convertir les objets que je reçois de la bibliothèque en instances de ma propre classe.

0 votes

La question suivante pourrait vous intéresser [avertissement : c'est moi qui l'ai posée] : stackoverflow.com/questions/990758/

0 votes

Faites attention. Les avertissements affichés par certains des répondeurs ne sont pas à sous-estimer.

0 votes

Cela n'a pas l'air très lisible, je vais probablement changer mon code en utilisant l'héritage pour encapsuler l'autre objet à la place.

3voto

upandacross Points 41

J'ai une situation similaire, à la différence que la nouvelle classe ne doit copier que les attributs. Ainsi, en utilisant l'idée de @Dunham et en ajoutant un peu de spécificité à la suggestion de @meisterluk, la méthode "copy_constructor" de @meisterluk pourrait être :

from copy import deepcopy
class Foo(object):
    def __init__(self, myOne=1, other=None):
    self.two = 2
    if other <> None:
        assert isinstance(other, Foo), "can only copy instances of Foo"
        self.__dict__ = deepcopy(other.__dict__)
    self.one = myOne

def __repr__(self):
    out = ''
    for k,v in self.__dict__.items():
        out += '{:>4s}: {}, {}\n'.format(k,v.__class__,v)
    return out

def bar(self):
    pass

foo1 = Foo()
foo2 = Foo('one', foo1)

print '\nfoo1\n',foo1
print '\nfoo2\n',foo2

Le résultat :

foo1
 two: <type 'int'>, 2
 one: <type 'int'>, 1

foo2
 two: <type 'int'>, 2
 one: <type 'str'>, one

2voto

user10815638 Points 99

La solution suivante répète probablement certaines des précédentes sous une forme simple. Je ne sais pas si elle est "pythologiquement" correcte, mais elle fonctionne et était très pratique dans le cas précis où je l'ai utilisée.

class Entity:
    def __init__(self, code=None, name=None, attrs=None):
        self.code = code
        self.name = name
        self.attrs = {} if attrs is None else attrs

    def copy(self, attrs=None):
        new_attrs = {k: v.copy() for k, v in self.attrs.items()} if attrs is None else attrs
        return Entity(code=self.code, name=self.name, attrs=new_attrs)

Utilisation :

new_entity = entity.copy()

C'est une version plus compliquée qui permet d'intervenir dans le processus de copie. Je l'ai utilisé à un seul endroit. Notez également que les objets contenus dans self.attrs ont aussi ce genre de "constructeur de copie".

Cette solution n'est pas générique, mais elle est très simple et permet un contrôle important.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X