Pythonコンストラクタと__init__


107

コンストラクタが実際に「コンストラクタ」と呼ばれるのはなぜですか?それらの目的は何ですか?それらはクラスのメソッドとどのように違うのですか?

また、__init__クラスにはそれ以上の人がいますか?私は以下を試しました、誰かが結果を説明できますか?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"

>>> s=test()
init 2

最後に__init__、オペレーターはオーバーローダーですか?


41
技術的に__init__は、イニシャライザです。Python コンストラクタ__new__です。Pythonは自動2フェーズ初期化を使用します- __new__有効だが(通常は)未入力のオブジェクト(bool反例についてはを参照)を返し、オブジェクトは__init__自動的に呼び出されます。これにより、C ++のような言語が部分的に構築されたオブジェクトに伴う問題が回避されます-Pythonにはオブジェクトがありません(ただし、部分的に初期化されている場合があります)。両方をオーバーライドする必要はほとんどありません__new__し、__init__クラスに。
Tim Delaney、2012年

2
@TimDelaney:C ++で部分的に構築されたオブジェクトの意味がわかりません。
セバスチャンマッハ

11
@phresnel C ++では、オブジェクトのタイプは、基本クラスコンストラクター内では(サブクラスではなく)基本クラスです。基本クラスのコンストラクターで仮想メソッドを呼び出して、サブクラスに実装を提供させることはできません。Javaでは、基本クラスコンストラクターでサブクラスメソッドを呼び出すことができますが、サブクラスメンバー変数は、基本クラスコンストラクター(およびメソッド呼び出し)の後に自動的に初期化さます。Pythonのような2フェーズの初期化を行う言語では、基本クラスの初期化子でメソッドを喜んで呼び出すことができ、サブクラスに動作を提供(またはオーバーライド)させることができます。
ティム・デラニー

@TimDelaney:ああ、説明してくれてありがとう。
セバスチャンマッハ

4
@TimDelaney。私はあなたのコメントが受け入れられた答えを置き換えるべきだと思います。
フラメンコ

回答:


114

Pythonには関数のオーバーロードはありません。つまり、名前が同じで引数が異なる関数を複数持つことはできません。

コード例では、オーバーロードし ていません__init__()。2番目の定義が名前を新しいメソッドに再バインド__init__、最初のメソッドにアクセスできなくなることが起こります。

コンストラクターに関する一般的な質問については、ウィキペディアが出発点として適しています。Python固有のものについては、私は強くお勧めします Pythonのドキュメントます。


また、ソースファイルが順番に解析(解釈)されることを意味しますか?後で定義した関数が以前に同じ名前で定義された関数を上書きすることを確認できますか?:(私のQはばかげて聞こえる..それを知っているはずだった
0xc0de

4
@ 0xc0de:Pythonでは、関数定義は実際には実行可能なステートメントであり、上から下に実行されるため、はい。
NPE、2012年

1
@ 0xc0de実際に起こることは、クラスの本体がそれ自体の名前空間で実行され、その名前空間が(名前とベースとともに)メタクラスに渡されることです。関数定義は、指定された本体で関数を作成し、その名前に割り当てるだけです。への最後の割り当て__init__は、クラスで最終的に何になるかです。
2015

64

コンストラクタが実際に「コンストラクタ」と呼ばれるのはなぜですか?

コンストラクター(という名前__new__)は、クラスの新しいインスタンスを作成して返します。したがって、C.__new__クラスメソッドはコンストラクタですクラスCのです。

C.__init__それが作成された後、インスタンスメソッドは、呼び出し元に戻される前に、それを初期化するために、特定のインスタンスで呼び出されます。したがって、そのメソッドはCの新しいインスタンスの初期化子です。

それらはクラスのメソッドとどう違うのですか?

で述べたように公式ドキュメント __init__されるインスタンスが作成された後に呼び出されます。他の方法はこの治療を受けません。

彼らの目的は何ですか?

コンストラクターの目的は、C.__new__新しいCインスタンスの構築中にカスタム動作を定義することです。

初期化子の目的は、C.__init__の各インスタンスのカスタム初期化を定義することですC作成後ことです。

たとえば、Pythonでは次のことができます。

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

しかし、のすべてのインスタンスに10に等しいTest属性を持たせたい場合はx、そのコードを内部に配置できます__init__

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

すべてのインスタンスメソッド(クラスの特定のインスタンスで呼び出されるメソッド)は、最初の引数としてインスタンスを受け取ります。その引数は慣習的に名前が付けられていselfます。

コンストラクタなどのクラスメソッドは__new__、代わりにクラスを最初の引数として受け取ります。

ここで、x属性のカスタム値が必要な場合は、その値を引数としてに渡すだけです__init__

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

これがいくつかの疑問を解消するのに役立つことを願っています。すでに他の質問に対する良い回答を受け取っているので、ここで止めます:)


9

クラスは、オブジェクトを作成するための単なる青写真です。コンストラクターは、オブジェクトを作成するたびに実行されるいくつかのコードです。そのため、2つのコンストラクターを持つことは意味がありません。何が起こるかは、2番目が最初を上書きすることです。

これらを通常使用するのは、次のようにそのオブジェクトの変数を作成することです。

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

したがって、このクラスから次のようにオブジェクトを作成することができます。

>>> testobject = testing(5)

テストオブジェクトにはsome_value、このサンプルでは5 と呼ばれるオブジェクトがあります。

>>> testobject.some_value
5

しかし、サンプルで行ったように、各オブジェクトに値を設定する必要はありません。次のようにすることもできます:

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

その場合、some_valueの値は5になり、オブジェクトの作成時に設定する必要はありません。

>>> testobject = testing()
>>> testobject.some_value
5

>>>と...私のサンプルでは、​​あなたが書いたものではありません。それはpyshellでどのように見えるかです...


問題ありません、それがあなたを助けてくれてうれしいです:)
Niclas Nilsson

1

coonstructorsは、新しいオブジェクトを作成するときに自動的に呼び出され、それによってオブジェクトを「構築」します。複数のinitを使用できるのは、名前がpythonの単なる参照であり、各変数が参照するものをいつでも変更できるためです(動的型付け)

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

クラス定義では、後の方を保持します


0

Pythonには、メソッドのオーバーロードの概念はありません。ただし、オプションの引数とキーワード引数を指定することで、同様の効果を得ることができます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.