Подтвердить что ты не робот

Создать новый экземпляр класса из метода класса

Я хочу иметь возможность создать новый экземпляр объекта, вызвав метод на уже созданный объект. Например, у меня есть объект:

organism = Organism()

Я хочу иметь возможность называть organism.reproduce() и иметь два объекта типа Organism. Мой метод в этот момент выглядит следующим образом:

class Organism(object):
    def reproduce():
        organism = Organism()

и я уверен, что он не работает (я даже не уверен, как его протестировать. Я пробовал gc-метод в этом сообщении), Итак, как я могу сделать свой объект созданием самой копии, доступной так же, как и первый созданный мной объект (с organism = Organism())?

4b9b3361

Ответ 1

class Organism(object):
    def reproduce(self):
        #use self here to customize the new organism ...
        return Organism()

Другая опция - если экземпляр (self) не используется в методе:

class Organism(object):
    @classmethod
    def reproduce(cls):
        return cls()

Это гарантирует, что Организмы производят больше Организмов и (гипотетические Борги, которые происходят от Организмов, производят больше Боргов).

Боковое преимущество использования self заключается в том, что теперь его можно вызывать из класса непосредственно в дополнение к возможности вызова из экземпляра:

new_organism0 = Organism.reproduce()  # Creates a new organism
new_organism1 = new_organism0.reproduce()  # Also creates a new organism

Наконец, если в методе используются как экземпляр (self), так и класс (Organism или подклассы, если они вызваны из подкласса):

class Organism(object):
    def reproduce(self):
        #use self here to customize the new organism ...
        return self.__class__()  # same as cls = type(self); return cls()

В каждом случае вы будете использовать его как:

organism = Organism()
new_organism = organism.reproduce()

Ответ 2

Почему бы просто не использовать модуль копирования?

import copy
organism = Organism()
replica = copy.deepcopy(organism)

Ответ 3

То же самое, что вы делали изначально, но тогда вам нужно что-то сделать с ним!

organism = Organism() вызывает класс Organism (круглые скобки непосредственно после имени - это операция "вызов" ). Это создает и возвращает новый экземпляр класса, который затем привязывается к имени Organism.

Когда вы выполняете эту строку в интерпретаторе, теперь у вас есть переменная Organism, ссылающаяся на новый экземпляр Organism, который вы только что создали.

Когда вы пишете эту строку внутри функции (включая метод, потому что нет никакой разницы между методом и функцией "изнутри" ), он делает то же самое, но переменная Organism является локальной переменной. Локальные переменные отбрасываются, когда функция завершена, поэтому создается новый экземпляр Organism, но он ничего не добивается, потому что вы никогда не получаете к нему доступа.

Ваша функция должна возвращать любую информацию, которую он хочет сообщить своему вызывающему абоненту. Любые локальные переменные, которые вы не возвращаете, полезны, только если вы используете эти переменные для создания того, что вы возвращаете.

Обратите внимание, что это не имеет никакого отношения к вашей конкретной проблеме создания экземпляра внутри метода; это то, как работают функции/методы в целом. Вам нужно будет узнать, как работают функции, прежде чем вы сможете успешно писать объектно-ориентированные программы, используя классы и экземпляры; Я настоятельно рекомендую вам работать с некоторыми учебниками.

Ответ 4

Что-то вроде этого:

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]

Результат:

>>> 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

Ответ 5

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