8.4 构造函数
对于一个新定义的类,我们之所以能够用类似于这样的语句: stu=Student() 来声明一个新的对象,其实是调用了一个函数,这个函数叫做构造函数。
什么是构造函数呢,有什么作用呢?
构造函数的作用是给新创建的对象分配内存,初始化属性的值。对于分配内存,我们不用做什么,编译器已经做好了,我们要自己写的是后面的那个:初始化属性。事实上,你就算是一个这样的类,里面什么都没有:
class Chapter:pass
即使这个类貌似什么“内容”都没有
,编译器也自动给你添加了一个没有参数的构造函数,这个自动添加的构造函数,使得你可以创建对象,例如这样:
c = Chapter()
虽然编译器会提供一个缺省构造函数,但我们通常需要手动写,__init__就是构造函数首先自动调用的函数(注意是"两个下划线+init+两个下划线"),我们在此章节把init和构造函数当做同义词:
class Chapter: def __init__(self): print("构造函数被调用") self.id = 1000 self.code = "" self.name = "" self.content = "" self.parentCode = ""c = Chapter()c2 = Chapter()c1 = Chapter()c4 = Chapter()print(c.id)
1. init函数没有返回值,但是构造函数把生成的对象返回
2. 如果没有写构造函数,编译器会提供一个无参数构造函数
3. init函数只能有一个
4. 通常把属性的定义直接写在构造函数里
这里也展示了python类通常的写法:在构造函数里定义属性。
代码执行的时候,“构造函数被调用”会打出4次,因为声明了4个Chapter对象,最终打印的1000是因为c的id值在构造函数中初始化为1000。
python类的构造函数只能有一个。构造函数的参数可以自己定义。
假设id值是任何对象都必须要有的值,它很重要。那么我们可以写一个这样的构造函数:
class Chapter: def __init__(self,id): print("构造函数被调用") self.id = id self.code = "" self.name = "" self.content = "" self.parentCode = ""c = Chapter(8898)print(c.id)c2 = Chapter() #这行语法错误,因为没有无参数的构造函数
如果类里面没有任何构造函数,编译器会自动生成一个无参数的构造函数;如果类里面已经有构造函数,那么编译器不会生成无参数的构造函数。(你无我生成,你有我不管)。所以上面最后一行的代码错误了,因为已经没有无参数的构造函数,系统也不再提供。
这个构造函数需要一个参数,用来设置id值。那么新生成一个对象的时候,就可以这样调用了,Chapter对象c被创建,同时c的id属性赋值为8898,同时还可以生成一个新的对象c2,但什么属性都不设置,但这里会出语法错误,因为c2的构造函数参数数量不对。如果需要c2对象也生效,那么可以把id设置成缺省参数(函数参数默认值):
class Chapter: def __init__(self,id=1000): print("构造函数被调用") self.id = id self.code = "" self.name = "" self.content = "" self.parentCode = ""c = Chapter(8898)print(c.id)c2 = Chapter() print(c2.id)
如果有两个以上的参数,并且有缺省值,那么看下面的例子:
class Chapter: def __init__(self,id=1000,code=124587): print("构造函数被调用") self.id = id self.code = code self.name = "" self.content = "" self.parentCode = ""# 不指定任何参数,那么所有参数使用默认c = Chapter()print(c.id,c.code)# 指定参数为code,那么id值使用默认的1000c1=Chapter(code=1123)print(c1.id,c1.code)#不指定参数名,那么就从最左边参数开始匹配,1123就是参数idc2=Chapter(1123)print(c2.id,c2.code)#不指定参数名,那么就从最左边参数开始匹配,1123就是参数id,886就是codec3=Chapter(1123,886)print(c3.id,c3.code)