从对象方法创建新对象(类实例)[重复]

问题描述 投票:0回答:6

我希望能够通过调用已实例化的对象上的方法来创建对象的新实例。例如,我有一个对象:

organism = Organism()

我希望能够调用

organism.reproduce()
并拥有两个有机体类型的对象。此时我的方法如下所示:

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

而且我很确定它不起作用(我什至不确定如何测试它。我在这篇文章中尝试了 gc 方法)。那么我怎样才能让我的对象创建一个可以访问的自身副本,就像我创建的第一个对象一样(使用

organism = Organism()
)?

python object copy
6个回答
101
投票
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()

3
投票

为什么不简单地使用复制模块?

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

3
投票

这样的事情怎么样:

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

1
投票

和你最初做的一样,但是你必须用它做点什么!

organism = Organism()
调用类
Organism
(名称后面紧跟着的括号是“调用”操作)。这将创建并返回该类的一个新实例,然后将其绑定到名称
organism

当您在解释器中执行该行时,您现在有一个变量

organism
引用您刚刚创建的新
Organism
实例。

当您在函数内部(包括方法,因为“从内部””方法和函数之间没有区别)编写该行时,它会执行相同的操作,但变量

organism
是一个 local 变量。当函数完成时,局部变量会被丢弃,所以这确实创建了一个新的
Organism
实例,但它没有实现任何目标,因为你永远无法访问它。

您的函数应该返回它想要与调用者通信的任何信息。您不返回的任何局部变量仅在您使用这些变量来创建您do返回的内容时才有用。

请注意,这与在方法内创建实例的特定问题“没有任何关系”;这就是函数/方法的一般工作方式。在使用类和实例成功编写面向对象的程序之前,您需要了解函数的工作原理;我强烈建议您学习一些教程。


1
投票

但是,在大多数情况下,您需要一致的行为(所有属性的深层复制或复制),在这种情况下,您可以使用

copy

模块作为


import copy new_obj = copy.copy(old_obj)

new_obj = copy.deepcopy(old_obj)

在您想要更加自定义的行为的一般情况下,您可以使用相同的命令,但覆盖对象的 
__copy__

__deepcopy__
方法。

查看更多答案以获取详细信息和示例,例如:

如何覆盖Python对象的复制/深复制操作?


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.