通过你所写的内容,你错过了一个重要的理解:一个类和一个对象之间的区别. __init__不初始化类,它初始化类或对象的实例.每只狗都有颜色,但狗作为一个类没有.每只狗有四个或更少的脚,但是这类狗没有.该类是对象的概念.当你看到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是一个名为变量self中对象的leg的属性.属性类似于变量,但它们描述了对象的状态,或对象可用的特定动作(函数).
但是,请注意,您没有为狗狗本身设置颜色 – 这是一个抽象的概念.有些属性在类上有意义.例如,population_size就是其中之一 – 计算Fido是没有意义的,因为Fido总是一个.数狗是有道理的.让我们说世界上有2亿只狗.这是Dog类的财产. Fido与2亿号无关,Spot也没有.它被称为“类属性”,而不是上面的颜色或腿的“实例属性”.
现在,对于更少的犬和更多的编程相关的东西.正如我在下面写的那样,添加东西的课程是不明智的 – 它是什么类? 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
这有点脆弱(我们假设其他人将是MyInteger),但我们现在会忽略.在实际代码中,我们不会;我们测试它以确保,甚至可能强制它(“你不是一个整数?通过golly,你有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)
有更多的分数而不是整数(不是真的,但计算机不知道这一点).我们来两个:
half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6
你实际上并没有在这里宣布任何事情.属性就像一种新的变量.正常变量只有一个值.让我们说你写color =“gray”.你不能有另一个名为color的变量是“fuchsia” – 不在代码的同一个地方.
数组在一定程度上解决了这个问题.如果你说color = [“grey”,“fuchsia”],你已经将两种颜色堆叠到变量中,但是你可以通过它们的位置来区分它们(在这种情况下为0或1).
属性是绑定到对象的变量.与数组一样,我们可以在不同的狗上有很多颜色变量.所以,fido.colour是一个变量,但spot.colour是另一个变量.第一个绑定到变量fido中的对象;第二,现货.现在,当你调用Dog(4,“brown”)或three.add(5)时,总会有一个不可见的参数,它将被分配给参数列表前面的悬空额外参数.它通常被称为self,它将获得点前面的对象的值.因此,在狗的__init__(构造函数)中,自我将成为新狗将会变成的任何东西;在MyInteger的add中,self将绑定到变量3中的对象.因此,three.value将是add之外的同一个变量,作为add中的self.value.
如果我说the_mangy_one = fido,我将开始引用另一个名称为fido的对象.从现在开始,fido.colour与the_mangy_one.colour完全相同.
那么,__ init__里面的东西.你可以把它们想象成狗的出生证明.颜色本身是一个随机变量,可以包含任何东西. fido.colour或者self.colour就像狗身份表上的表格字段;和__init__是第一次填写它的职员.
有更清楚的吗?
编辑:扩展以下评论:
你的意思是一个对象列表,不是吗?
首先,fido实际上不是一个对象.它是一个变量,当前包含一个对象,就像你说x = 5时一样,x是一个当前包含数字5的变量.如果你以后改变主意,你可以做fido = Cat(4,“赏心悦目”)(只要你创建了一个类Cat),从那时起fido会“包含”一个猫对象.如果你做fido = x,它将包含数字5,而不是动物对象.
除非您专门编写代码来跟踪它们,否则类本身不知道它的实例.例如:
class Cat:
census = [] #define census array
def __init__(self, legs, colour):
self.colour = colour
self.legs = legs
Cat.census.append(self)
在这里,人口普查是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
请注意,你不会[蓬松,闪闪发光].这些只是变量名.如果您希望猫自己拥有名称,则必须为名称创建单独的属性,然后覆盖__str__方法以返回此名称.这个方法(即类绑定函数,就像add或__init__)的目的是描述如何将对象转换为字符串,就像打印出来一样.