我希望能够通过调用已实例化的对象上的方法来创建对象的新实例。例如,我有一个对象:
organism = Organism()
我希望能够调用
organism.reproduce()
并拥有两个有机体类型的对象。此时我的方法如下所示:
class Organism(object):
def reproduce():
organism = Organism()
而且我很确定它不起作用(我什至不确定如何测试它。我在这篇文章中尝试了 gc 方法)。那么我怎样才能让我的对象创建一个可以访问的自身副本,就像我创建的第一个对象一样(使用
organism = Organism()
)?
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()
为什么不简单地使用复制模块?
import copy
organism = Organism()
replica = copy.deepcopy(organism)
这样的事情怎么样:
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
和你最初做的一样,但是你必须用它做点什么!
organism = Organism()
调用类 Organism
(名称后面紧跟着的括号是“调用”操作)。这将创建并返回该类的一个新实例,然后将其绑定到名称 organism
。
当您在解释器中执行该行时,您现在有一个变量
organism
引用您刚刚创建的新 Organism
实例。
当您在函数内部(包括方法,因为“从内部””方法和函数之间没有区别)编写该行时,它会执行相同的操作,但变量
organism
是一个 local 变量。当函数完成时,局部变量会被丢弃,所以这确实创建了一个新的Organism
实例,但它没有实现任何目标,因为你永远无法访问它。
您的函数应该返回它想要与调用者通信的任何信息。您不返回的任何局部变量仅在您使用这些变量来创建您do返回的内容时才有用。
请注意,这与在方法内创建实例的特定问题“没有任何关系”;这就是函数/方法的一般工作方式。在使用类和实例成功编写面向对象的程序之前,您需要了解函数的工作原理;我强烈建议您学习一些教程。