あなたが書いたものによって、あなたは重要な理解の欠落、つまりクラスとオブジェクトの違いを見逃しています。__init__
クラスを初期化するのではなく、クラスまたはオブジェクトのインスタンスを初期化します。各犬には色がありますが、クラスとしての犬にはありません。各犬の足は4本以下ですが、犬のクラスにはありません。クラスはオブジェクトの概念です。FidoとSpotを見ると、それらの類似性、犬らしさを認識しています。それがクラスです。
あなたが言う時
class Dog:
def __init__(self, legs, colour):
self.legs = legs
self.colour = colour
fido = Dog(4, "brown")
spot = Dog(3, "mostly yellow")
あなたが言っているのは、Fidoは4本足の茶色の犬であり、Spotは少し不自由でほとんど黄色です。この__init__
関数はコンストラクターまたは初期化子と呼ばれ、クラスの新しいインスタンスを作成すると自動的に呼び出されます。その関数内で、新しく作成されたオブジェクトがパラメーターに割り当てられますself
。表記self.legs
はlegs
、変数内のオブジェクトの属性と呼ばれますself
。属性は一種の変数ですが、オブジェクトの状態、またはオブジェクトで使用できる特定のアクション(関数)を記述します。
ただし、colour
ドッグフッド自体を設定するわけではないことに注意してください。これは抽象的な概念です。クラスには意味のある属性があります。たとえば、population_size
そのようなものです-Fidoは常に1つであるため、Fidoを数えるのは意味がありません。犬を数えるのは理にかなっています。世界には2億匹の犬がいるとしましょう。これはDogクラスのプロパティです。Fidoは2億という数字とは何の関係もなく、Spotも関係ありません。ある「インスタンスの属性」とは対照的に、それは、「クラス属性」と呼ばれていますcolour
またはlegs
上記の。
さて、より犬歯が少なく、よりプログラミング関連のものに。以下に書いているように、追加するクラスは賢明ではありません-それはどのクラスですか?Pythonのクラスは、同様に動作するさまざまなデータのコレクションで構成されます。犬のクラスは、FidoとSpotと199999999998に似た他の動物で構成され、すべてが街灯でおもらしをしています。物を追加するクラスは何で構成されていますか?それらに固有のどのデータによって、それらは異なりますか?そして、彼らはどのような行動を共有しますか?
しかし、数字...それらはより興味深い主題です。言う、整数。それらはたくさんありますが、犬よりもたくさんあります。Pythonにはすでに整数があることは知っていますが、(Pythonの整数をごまかして、使用することによって)馬鹿げたことをして「実装」してみましょう。
したがって、整数はクラスです。それらには、いくつかのデータ(値)といくつかの動作( "私をこの他の番号に追加する")があります。これを示しましょう:
class MyInteger:
def __init__(self, newvalue)
# imagine self as an index card.
# under the heading of "value", we will write
# the contents of the variable newvalue.
self.value = newvalue
def add(self, other):
# when an integer wants to add itself to another integer,
# we'll take their values and add them together,
# then make a new integer with the result value.
return MyInteger(self.value + other.value)
three = MyInteger(3)
# three now contains an object of class MyInteger
# three.value is now 3
five = MyInteger(5)
# five now contains an object of class MyInteger
# five.value is now 5
eight = three.add(five)
# here, we invoked the three's behaviour of adding another integer
# now, eight.value is three.value + five.value = 3 + 5 = 8
print eight.value
# ==> 8
これは少し壊れやすい(other
MyIntegerになると想定している)が、ここでは無視する。実際のコードでは、そうしません。私たちはそれを確かめるためにテストし、おそらくそれを強制することさえします(「あなたは整数ではないのですか?ゴーリーによって、あなたは1になるまでに10ナノ秒があります!9 ... 8 ....」)
分数を定義することもできます。分数は自分自身を追加する方法も知っています。
class MyFraction:
def __init__(self, newnumerator, newdenominator)
self.numerator = newnumerator
self.denominator = newdenominator
# because every fraction is described by these two things
def add(self, other):
newdenominator = self.denominator * other.denominator
newnumerator = self.numerator * other.denominator + self.denominator * other.numerator
return MyFraction(newnumerator, newdenominator)
整数よりもさらに小数があります(実際にはそうではありませんが、コンピューターはそれを知りません)。2つ作成しましょう。
half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6
ここでは実際には何も宣言していません。属性は新しい種類の変数のようなものです。通常の変数の値は1つだけです。あなたが書くとしましょうcolour = "grey"
。あなたは、名前の別の変数持つことができないcolour
で"fuchsia"
はないコード内の同じ場所にします- 。
配列はそれをある程度解決します。と言った場合colour = ["grey", "fuchsia"]
、2つの色を変数に積み上げていますが、それらの位置(この場合は0、または1)で区別しています。
属性は、オブジェクトにバインドされている変数です。配列の場合と同様colour
に、さまざまな犬にさまざまな変数を設定できます。つまり、fido.colour
1つの変数ですが、spot.colour
別の変数です。最初のものは変数内のオブジェクトにバインドされていますfido
。二、spot
。これでDog(4, "brown")
、またはを呼び出すと、three.add(five)
常に非表示のパラメーターが存在し、パラメーターリストの前にあるぶら下がりの追加パラメーターに割り当てられます。通常はと呼ばれself
、ドットの前にあるオブジェクトの値を取得します。したがって、犬__init__
(コンストラクター)内ではself
、新しい犬が何であるかがわかります。内MyInteger
s「はadd
、self
変数内のオブジェクトにバインドされますthree
。したがって、three.value
外部同じ変数であろうadd
ように、self.value
以内add
。
と言ったらthe_mangy_one = fido
、fido
別の名前で知られているオブジェクトを参照し始めます。これ以降、fido.colour
はとまったく同じ変数ですthe_mangy_one.colour
。
だから、内の事__init__
。それらは、犬の出生証明書に記載されているものと考えることができます。colour
それ自体は確率変数であり、何でも含むことができます。fido.colour
またはself.colour
、犬の身分証明書のフォームフィールドのようなもの。そして__init__
最初の時間のためにそれを記入店員です。
より明確ですか?
編集:以下のコメントを拡大:
あなたはオブジェクトのリストを意味しますね?
まず、fido
実際にはオブジェクトではありません。これは変数であり、現在オブジェクトを含んでいます。これはx = 5
、x
と言うのと同じように、現在5を含んでいる変数です。後で気が変わった場合はfido = Cat(4, "pleasing")
(クラスを作成している限りCat
)可能でありfido
、それ以降はcatオブジェクトを「含む」ことになります。そうした場合fido = x
、それはその後、数5、およびなく、すべての動物のオブジェクトが含まれています。
特に追跡するコードを記述しない限り、クラス自体はインスタンスを認識しません。例えば:
class Cat:
census = [] #define census array
def __init__(self, legs, colour):
self.colour = colour
self.legs = legs
Cat.census.append(self)
これcensus
は、クラスのクラスレベル属性ですCat
。
fluffy = Cat(4, "white")
spark = Cat(4, "fiery")
Cat.census
# ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>]
# or something like that
取得できないことに注意してください[fluffy, sparky]
。それらは単なる変数名です。猫自体に名前を付けたい場合は、名前に別の属性を作成し、__str__
メソッドをオーバーライドしてこの名前を返す必要があります。このメソッドの目的(つまり、add
またはのようなクラスバインド関数__init__
)は、オブジェクトを印刷するときのように、オブジェクトを文字列に変換する方法を説明することです。