さて、まず最初に。
Pythonには「変数宣言」や「変数初期化」などはありません。
単に「割り当て」と呼ぶものがありますが、おそらく単に「命名」と呼ぶべきです。
割り当てとは、「左側のこの名前は、以前に何を参照していたかに関係なく、右側を評価した結果を参照するようになりました」という意味です。
foo = 'bar'
foo = 2 * 3
そのため、Pythonの名前(おそらく「変数」よりも適切な用語)には、関連付けられた型がありません。値はそうです。タイプに関係なく、同じ名前を何にでも再適用できますが、そのタイプに依存する動作があります。名前は、値(オブジェクト)を参照するための単なる方法です。これは、2番目の質問に答えます。カスタム型を保持する変数を作成しません。特定の型を保持する変数を作成することはありません。変数を「作成」することはまったくありません。オブジェクトに名前を付けます。
2番目のポイント:Pythonは、クラスに関しては非常に単純なルールに従います。これは、Java、C ++、C#などの言語よりもはるかに一貫性があります。ブロック内で宣言されたものはすべてclass
クラスの一部です。したがって、def
ここで記述されている関数()はメソッドです。つまり、Java、C ++、C#の場合と同様に、クラスオブジェクトの一部です(インスタンスごとに格納されません)。しかし、ここにある他の名前もクラスの一部です。繰り返しになりますが、名前は単なる名前であり、関連付けられた型はありません。Pythonでは関数もオブジェクトです。したがって:
class Example:
data = 42
def method(self): pass
Pythonでは、クラスもオブジェクトです。
これで、sであるすべてのもののクラスを表すという名前のオブジェクトを作成しました。このオブジェクトには、ユーザーが指定した2つの属性があります(C ++では「メンバー」、C#では「フィールドまたはプロパティまたはメソッド」、Javaでは「フィールドまたはメソッド」)。そのうちの1つは、という名前で、整数値を格納します。もう1つは、という名前で、関数オブジェクトを格納します。(Pythonが自動的に追加する属性は他にもいくつかあります。)Example
Example
data
42
method
ただし、これらの属性はまだ実際にはオブジェクトの一部ではありません。基本的に、オブジェクトは、分割できないものにたどり着くまで、より多くの名前(属性名)のバンドルにすぎません。したがって、意図的に設定した場合は、クラスの異なるインスタンス間、または異なるクラスのオブジェクト間で値を共有できます。
インスタンスを作成しましょう:
x = Example()
x
これで、のインスタンスである、という名前の別のオブジェクトができましたExample
。data
そしてmethod
実際にオブジェクトの一部ではありませんが、我々はまだ経由でそれらを見ることができますx
ので、Pythonは背後でないことをいくつかの魔法の。method
特に、ルックアップすると、代わりに「バインドされたメソッド」x
が取得されます(これを呼び出すと、self
パラメーターとして自動的に渡されますExample.method
。直接ルックアップした場合は発生しません)。
使おうとするとx.data
どうなりますか?
それを調べると、最初にオブジェクトで検索されます。オブジェクトに見つからない場合、Pythonはクラスを調べます。
ただし、に割り当てると x.data
、Pythonはオブジェクトに属性を作成します。それはなりませんクラスの属性を交換してください。
これにより、オブジェクトの初期化を行うことができます。Pythonは__init__
、新しいインスタンスが存在する場合、それらが作成されるときに、クラスのメソッドを自動的に呼び出します。このメソッドでは、属性に割り当てるだけで、各オブジェクトにその属性の初期値を設定できます。
class Example:
name = "Ignored"
def __init__(self, name):
self.name = name
ここでname
、を作成するときにを指定する必要があり、Example
各インスタンスには独自のがありname
ます。インスタンスの属性が最初に見つかるため、PythonはインスタンスExample.name
を検索するたびにクラス属性を無視します.name
。
最後の注意点:変更(変更)と割り当ては別のものです!
Pythonでは、文字列は不変です。それらは変更できません。あなたがするとき:
a = 'hi '
b = a
a += 'mom'
あなたは変更されません、元の「ハイテク」の文字列を。それはPythonでは不可能です。代わりに、あなたが作成し、新しい文字列を'hi mom'
、そして原因はa
の名前であることを停止する'hi '
、との名前であることを開始'hi mom'
代わりに。私たちは、作られたb
の名前を'hi '
だけでなく、再適用した後a
の名前、b
まだの名前である'hi '
ため、'hi '
まだ存在して変更されていません。
ただし、リストは変更できます。
a = [1, 2, 3]
b = a
a += [4]
今、b
私たちが作っているため、[1、2、3、4]と同様であるb
ことを同じ事の名前a
の名前をした後、私たちはそのことを変えました。a
Pythonは単に+=
リストの扱いが異なるため、名前を付けるための新しいリストは作成しませんでした。
これはオブジェクトにとって重要です。クラス属性としてリストがあり、インスタンスを使用してリストを変更した場合、変更は他のすべてのインスタンスで「認識」されるためです。これは、(a)データが実際にはクラスオブジェクトの一部であり、インスタンスオブジェクトではないためです。(b)リストを変更していて、単純な割り当てを行っていないため、クラス属性を非表示にする新しいインスタンス属性を作成しませんでした。