50

既にインスタンス化されたオブジェクトでメソッドを呼び出して、オブジェクトの新しいインスタンスを作成できるようにしたいと考えています。たとえば、次のオブジェクトがあります。

organism = Organism()

organism.reproduce()Organism 型の 2 つのオブジェクトを呼び出して取得できるようにしたいと考えています。この時点での私の方法は次のようになります。

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

そして、それが機能しないことは確かです(テスト方法もよくわかりません。この投稿でgcメソッドを試しました)。では、( を使用して) 最初に作成したオブジェクトと同じように、オブジェクトに自分自身のコピーを作成させるにはどうすればよいorganism = Organism()でしょうか?

4

6 に答える 6

81
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()
于 2012-11-06T22:40:00.403 に答える
3

単にコピーモジュールを使用しないのはなぜですか?

import copy
organism = Organism()
replica = copy.deepcopy(organism)
于 2012-11-06T22:44:31.177 に答える
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
于 2012-11-06T23:34:29.393 に答える
1

最初にやったのと同じ方法ですが、それで何かをしなければなりません!

organism = Organism()クラスを呼び出しますOrganism(名前の直後の括弧は「呼び出し」操作です)。これにより、クラスの新しいインスタンスが作成されて返されます。これを name にバインドしますorganism

インタープリターでその行を実行すると、作成したばかりorganismの新しいOrganismインスタンスを参照する変数が作成されます。

その行を関数内 (メソッドを含む。"内部から" メソッドと関数に違いはないため) を記述すると、同じことが行われますが、変数organismローカル変数です。関数が終了するとローカル変数は破棄されるため、これにより新しいインスタンスOrganism作成されますが、アクセスできないため何も達成されません。

関数は、呼び出し元に伝えたい情報を返す必要があります。返さないローカル変数は、それらの変数を使用して返すものを作成する場合にのみ役立ちます。

これは、メソッド内でインスタンスを作成するという特定の問題とは関係がないことに注意してください。関数/メソッドが一般的にどのように機能するかだけです。クラスとインスタンスを使用してオブジェクト指向プログラムを作成する前に、関数がどのように機能するかを学習する必要があります。いくつかのチュートリアルに取り組むことを強くお勧めします。

于 2012-11-06T22:51:29.147 に答える
1

オブジェクトをコピーする方法を尋ねていると思います。驚くべきことに (おそらく)、これには (ほとんど) 標準的な方法はなく、これは設計によるものです。この問題は、コピーの概念に内在するあいまいさから生じます。つまり、オブジェクト プロパティをコピーする場合、それを参照 (コピー) としてコピーすることを意味するのでしょうか、それとも値 (ディープコピー) としてコピーすることを意味するのでしょうか?

ただし、ほとんどの場合、一貫した動作 (すべてのプロパティのディープコピーまたはコピー) が必要です。この場合、copyモジュールを次のように使用できます。

import copy
new_obj = copy.copy(old_obj)

また

new_obj = copy.deepcopy(old_obj)

よりカスタマイズされた動作が必要な一般的なケースでは、同じコマンドを使用しますが、オブジェクトのメソッド__copy____deepcopy__メソッドをオーバーライドします。

詳細と例については、その他の回答を参照してください。たとえば 、Python オブジェクトのコピー/ディープコピー操作をオーバーライドする方法は?

于 2020-01-13T09:48:36.397 に答える
0
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 
于 2012-11-06T22:45:47.193 に答える