Je veux pouvoir créer une nouvelle instance d'un objet en appelant une méthode sur un objet déjà instancié. Par exemple, j'ai l'objet:
organism = Organism()
Je veux pouvoir appeler organism.reproduce()
et avoir deux objets de type Organism. Ma méthode à ce stade ressemble à ceci:
class Organism(object):
def reproduce():
organism = Organism()
et je suis à peu près sûr que cela ne fonctionne pas (je ne sais même pas vraiment comment le tester. J'ai essayé la méthode gc dans ce post ). Alors, comment puis-je faire en sorte que mon objet crée une copie de lui-même accessible comme le premier objet que j'ai créé (avec organism = Organism()
)?
class Organism(object):
def reproduce(self):
#use self here to customize the new organism ...
return Organism()
Une autre option - si l'instance (self
) n'est pas utilisée dans la méthode:
class Organism(object):
@classmethod
def reproduce(cls):
return cls()
Cela garantit que les organismes produisent plus d'organismes et (les Borgs hypothétiques qui sont dérivés d'organismes produisent plus de Borgs).
Un avantage secondaire de ne pas avoir besoin d'utiliser self
est que cela peut maintenant être appelé directement depuis la classe en plus de pouvoir être appelé depuis une instance:
new_organism0 = Organism.reproduce() # Creates a new organism
new_organism1 = new_organism0.reproduce() # Also creates a new organism
Enfin, si l'instance (self
) et la classe (Organism
ou les sous-classes si elles sont appelées à partir d'une sous-classe) sont utilisées dans la méthode:
class Organism(object):
def reproduce(self):
#use self here to customize the new organism ...
return self.__class__() # same as cls = type(self); return cls()
Dans chaque cas, vous l'utiliseriez comme:
organism = Organism()
new_organism = organism.reproduce()
Et quelque chose comme ça:
class Organism(object):
population = []
def __init__(self, name):
self.name = name
self.population.append(self)
def have_one_child(self, name):
return Organism(name)
def reproduce(self, names):
return [self.have_one_child(name) for name in names]
Résultat:
>>> a = Organism('a')
>>> len(Organism.population)
1
>>> a.reproduce(['x', 'y', 'z']) # when one organism reproduces, children are added
# to the total population
# organism produces as many children as you state
[<__main__.Organism object at 0x05F23190>, <__main__.Organism object at 0x05F230F0>, <__main__.Organism object at 0x05F23230>]
>>> for ele in Organism.population:
... print ele.name
...
a
x
y
z
>>> Organism.population[3].reproduce(['f', 'g'])
[<__main__.Organism object at 0x05F231D0>, <__main__.Organism object at 0x05F23290>]
>>> for ele in Organism.population:
... print ele.name
...
a
x
y
z
f
g
pourquoi ne pas simplement utiliser le module de copie?
import copy
organism = Organism()
replica = copy.deepcopy(organism)
De la même manière que vous l'avez fait à l'origine, mais ensuite vous devez en faire quelque chose!
organism = Organism()
appelle la classe Organism
(les parenthèses directement après un nom sont l'opération "call"). Cela crée et renvoie une nouvelle instance de la classe, que vous liez ensuite au nom organism
.
Lorsque vous exécutez cette ligne dans l'interpréteur, vous disposez désormais d'une variable organism
faisant référence à la nouvelle instance Organism
que vous venez de créer.
Lorsque vous écrivez cette ligne dans une fonction (y compris une méthode, car il n'y a pas de différence entre une méthode et une fonction "de l'intérieur"), cela fait la même chose, mais la variable organism
est un local variable. Les variables locales sont supprimées lorsque la fonction est terminée, donc cela fait crée une nouvelle instance de Organism
, mais elle n'obtient rien parce que vous n'y avez jamais accès.
Votre fonction doit retourner toute information qu'elle souhaite communiquer à son appelant. Toutes les variables locales que vous ne retournez pas ne sont utiles que si vous utilisez ces variables pour créer quelque chose que vous faites retournez.
Notez que cela a rien à voir avec votre problème particulier de création d'une instance à l'intérieur d'une méthode; c'est juste comment les fonctions/méthodes fonctionnent en général. Vous devrez apprendre le fonctionnement des fonctions avant de pouvoir écrire avec succès des programmes orientés objet à l'aide de classes et d'instances; Je vous suggère fortement de suivre quelques tutoriels.
from copy import copy
class Organism(object):
def __init__(self,name):
self.name=name
def setName(self,name):
self.name=name
def reproduce(self,childname):
#use deepcopy if necessary
cp = copy(self)
cp.setName("descendant from " + self.name + " " + childname)
return cp
def __str__(self):
return self.name
first = Organism("first")
second = first.reproduce("second")
print first
print second