すでにインスタンス化されたオブジェクトのメソッドを呼び出すことにより、オブジェクトの新しいインスタンスを作成できるようにしたいと思います。たとえば、私はオブジェクトを持っています:
organism = Organism()
organism.reproduce()
を呼び出して、Organism型の2つのオブジェクトを持つことができるようにしたいと思います。この時点での私の方法は次のようになります。
_class Organism(object):
def reproduce():
organism = Organism()
_
そして、私はそれが動作しないことをかなり確信しています(私はそれをどのようにテストするかさえ本当に確信がありません。 this post で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()
このようなものはどうですか:
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
単純にコピーモジュールを使用しないのはなぜですか?
import copy
organism = Organism()
replica = copy.deepcopy(organism)
元々同じ方法でしたが、それを使って何かをしなければなりません!
organism = Organism()
はクラスOrganism
を呼び出します(名前の直後の括弧は「呼び出し」操作です)。これにより、クラスの新しいインスタンスが作成されて返され、_organism
という名前にバインドされます。
インタープリターでその行を実行すると、作成したばかりの新しいorganism
インスタンスを参照する変数Organism
があります。
関数内にその行を書くと(メソッドと、「内部から」メソッドと関数に違いがないため)、同じことをしますが、変数organism
はlocal変数。関数が終了するとローカル変数は破棄されるため、これはdoesが新しいOrganism
インスタンスを作成しますが、何も達成しません決してアクセスできないからです。
関数は、呼び出し元と通信したい情報をreturnする必要があります。返さないローカル変数は、それらの変数を使用してdoが返すものを作成する場合にのみ役立ちます。
これは、メソッド内にインスタンスを作成するという特定の問題に関連するnothingを持っていることに注意してください。それは関数/メソッドが一般的にどのように機能するかだけです。クラスとインスタンスを使用してオブジェクト指向プログラムを正常に作成するには、関数がどのように機能するかを学習する必要があります。いくつかのチュートリアルを進めることを強くお勧めします。
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