Why do we use __init__ in Python classes?
我无法理解类的初始化。
它们的意义是什么?我们如何知道在它们中包含什么?在类中写作是否需要一种不同类型的思考,而不是创建函数(我认为我可以只创建函数,然后将它们包装在类中,这样我就可以重用它们了)。这样行吗?)
下面是一个例子:
1 2 3 4 5 6 7 8 9 10 | class crawler: # Initialize the crawler with the name of database def __init__(self,dbname): self.con=sqlite.connect(dbname) def __del__(self): self.con.close() def dbcommit(self): self.con.commit() |
或其他代码示例:
1 2 3 4 5 6 7 | class bicluster: def __init__(self,vec,left=None,right=None,distance=0.0,id=None): self.left=left self.right=right self.vec=vec self.id=id self.distance=distance |
当我试图读取其他人的代码时,会遇到很多使用
根据你所写的,你缺少了一个关键的理解:类和对象之间的区别。
当你说好的。
1 2 3 4 5 6 7 | class Dog: def __init__(self, legs, colour): self.legs = legs self.colour = colour fido = Dog(4,"brown") spot = Dog(3,"mostly yellow") |
你是说,菲多是一只棕色的四条腿的狗,而斑点是一个有点残废,大多是黄色的。
但是,请注意,您没有为教条本身设置
现在,对于一些与狗和编程相关的东西来说。正如我在下面写的,类添加东西是不明智的-它是什么类?Python中的类由不同的数据集合组成,它们的行为类似。狗类包括fido和spot以及19999999998其他类似的动物,它们都在灯柱上撒尿。添加内容的类由什么组成?它们固有的数据有什么不同?他们共同采取了哪些行动?好的。
但是,数字…这些是比较有趣的科目。比如说整数。他们有很多,比狗还多。我知道python已经有了整数,但是让我们装傻,再次"实现"它们(通过欺骗和使用python的整数)。好的。
所以,整数是一个类。他们有一些数据(价值)和一些行为("把我加到另一个数字上")。让我们展示一下:好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
这有点脆弱(我们假设
我们甚至可以定义分数。分数也知道如何添加自己。好的。
1 2 3 4 5 6 7 8 9 | 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) |
分数甚至比整数还要多(不是真的,但计算机不知道)。让我们做两个:好的。
1 2 3 4 5 6 7 | half = MyFraction(1, 2) third = MyFraction(1, 3) five_sixths = half.add(third) print five_sixths.numerator # ==> 5 print five_sixths.denominator # ==> 6 |
你在这里什么都没说。属性就像一种新的变量。正常变量只有一个值。假设你写信给
数组在一定程度上解决了这个问题。如果你说
属性是绑定到对象的变量。像数组一样,我们可以在不同的狗上有大量的
如果我说
所以,在
更清楚些吗?好的。
编辑:展开以下评论:好的。
你是说一张物品清单,不是吗?好的。
首先,
类本身并不知道它的实例,除非您专门编写代码来跟踪它们。例如:好的。
1 2 3 4 5 6 7 | class Cat: census = [] #define census array def __init__(self, legs, colour): self.colour = colour self.legs = legs Cat.census.append(self) |
这里,
1 2 3 4 5 | fluffy = Cat(4,"white") spark = Cat(4,"fiery") Cat.census # ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>] # or something like that |
注意,你不会得到
为阿玛丹的彻底解释贡献我的5美分。
其中类是抽象的"类型"描述。物体是它们的意识:活生生的呼吸物。在面向对象的世界里,你几乎可以称之为一切事物的本质。他们是:
对象具有一个或多个特征(=属性)和行为(=方法)。行为主要取决于特征。类以一般的方式定义行为应该完成什么,但是只要类没有作为对象实现(实例化),它仍然是一个抽象的可能性概念。让我用"继承"和"多态性"来说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | class Human: gender nationality favorite_drink core_characteristic favorite_beverage name age def love def drink def laugh def do_your_special_thing class Americans(Humans) def drink(beverage): if beverage != favorite_drink: print"You call that a drink?" else: print"Great!" class French(Humans) def drink(beverage, cheese): if beverage == favourite_drink and cheese == None: print"No cheese?" elif beverage != favourite_drink and cheese == None: print"Révolution!" class Brazilian(Humans) def do_your_special_thing win_every_football_world_cup() class Germans(Humans) def drink(beverage): if favorite_drink != beverage: print"I need more beer" else: print"Lecker!" class HighSchoolStudent(Americans): def __init__(self, name, age): self.name = name self.age = age jeff = HighSchoolStudent(name, age): hans = Germans() ronaldo = Brazilian() amelie = French() for friends in [jeff, hans, ronaldo]: friends.laugh() friends.drink("cola") friends.do_your_special_thing() print amelie.love(jeff) >>> True print ronaldo.love(hans) >>> False |
一些特征定义了人类。但是每一个民族都有所不同。因此,"民族类型"有点像人类,有着额外的东西。美国人是"人类"的一种类型,从人类类型(基本类)继承了一些抽象的特征和行为:那就是继承。所以所有的人都可以笑和喝,所以所有的儿童班也可以!继承(2)。
但是,由于它们都是同一类(类型/基类:人类),您有时可以交换它们:请参见末尾的for循环。但它们会暴露出一个个体特征,这就是多态性(3)。
所以每个人都有自己最喜欢的饮料,但是每个民族都倾向于一种特殊的饮料。如果你将一个民族从人类的类型中分出来,你就可以覆盖继承的行为,正如我上面用
1 | hans = German(favorite_drink ="Cola") |
实例化类German,并在开始时"更改"默认特性。(但如果你叫汉斯喝牛奶),他还是会印上"我需要更多的啤酒"-一个明显的错误…或者,如果我是一家大公司的员工,这可能就是我所说的功能。!)
例如德语(hans)类型的特征通常在实例化时通过构造函数(在python:
但是因为每个对象都是一个类的实例,所以它们共享所有基本的特征类型和一些行为。这是面向对象概念的一个主要优势。
为了保护每个对象的特性,您封装了它们——意味着您试图将行为和特性结合起来,并使从对象外部对其进行操作变得困难。这就是封装(1)
它只是初始化实例的变量。
例如,使用特定的数据库名称(从上面的示例中)创建一个
如果要正确初始化实例的可变属性,似乎需要在python中使用
请参见以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | >>> class EvilTest(object): ... attr = [] ... >>> evil_test1 = EvilTest() >>> evil_test2 = EvilTest() >>> evil_test1.attr.append('strange') >>> >>> print"This is evil:", evil_test1.attr, evil_test2.attr This is evil: ['strange'] ['strange'] >>> >>> >>> class GoodTest(object): ... def __init__(self): ... self.attr = [] ... >>> good_test1 = GoodTest() >>> good_test2 = GoodTest() >>> good_test1.attr.append('strange') >>> >>> print"This is good:", good_test1.attr, good_test2.attr This is good: ['strange'] [] |
这在Java中是完全不同的,其中每个属性都用一个新的值自动初始化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import java.util.ArrayList; import java.lang.String; class SimpleTest { public ArrayList<String> attr = new ArrayList<String>(); } class Main { public static void main(String [] args) { SimpleTest t1 = new SimpleTest(); SimpleTest t2 = new SimpleTest(); t1.attr.add("strange"); System.out.println(t1.attr +"" + t2.attr); } } |
产生我们直观预期的输出:
1 | [strange] [] |
但是,如果您声明
1 | [strange] [strange] |
类是具有特定于该对象的属性(状态、特征)和方法(函数、容量)的对象(分别为duck的white color和fly powers)。
当你创建一个类的实例时,你可以给它一些初始的个性(状态或角色,比如新生儿的名字和衣服的颜色)。你用
基本上,当您调用
以你的汽车为例:当你得到一辆车时,你只是没有随机得到一辆车,我的意思是,你选择了颜色、品牌、座位数量等,有些东西也会"初始化",而你没有选择,比如车轮数量或注册号。
1 2 3 4 5 6 7 | class Car: def __init__(self, color, brand, number_of_seats): self.color = color self.brand = brand self.number_of_seats = number_of_seats self.number_of_wheels = 4 self.registration_number = GenerateRegistrationNumber() |
因此,在
1 | my_car = Car('blue', 'Renault', 2) |
这样,我们就创建了一个
- 关于python中类的更多信息
- 关于
__init__ 方法的更多信息
1 2 | mycluster = bicluster(...actual values go here...) mycluster.left # returns the value passed in as 'left' |
查看python文档了解一些信息。你会想拿起一本关于OO概念的书继续学习。
1 2 3 4 5 6 7 8 | class Dog(object): # Class Object Attribute species = 'mammal' def __init__(self,breed,name): self.breed = breed self.name = name |
在上面的例子中,我们使用物种作为一个整体,因为它总是相同的(你可以说是一种常数)。当调用
1 2 3 4 5 6 7 | class Dog(object): a = '12' def __init__(self,breed,name,a): self.breed = breed self.name = name self.a= a |
如果您像这样调用下面的代码来打印上面的示例
1 2 3 4 5 6 | Dog.a 12 Dog('Lab','Sam','10') Dog.a 10 |
这意味着它将只在对象创建期间初始化。所以,任何你想声明为常量的东西都将其设置为全局的,任何更改都使用