基本介绍
构造方法(构造器)基本语法
def __init__(self, 参数列表)
代码
功能:完成对象的初始化任务
1)在初始化对象时,会自动执行__init__方法(创建几个对象,就会执行几次__init__方法)
我们编写程序来验证这个结论,程序如下。
class Person:
# 构造方法/构造器
def __init__(self):
print("__init__执行了!")
p1 = Person()
p2 = Person()
程序执行结果为:
__init__执行了!
__init__执行了!
我们可以看到,__init__方法被执行了两次。
2)在初始化对象时,将传入的参数自动传递给__init__方法
class Person:
# 构造方法/构造器
def __init__(self, name, age):
print(f"姓名: {name};年龄: {age}")
p1 = Person("小白", 20)
# 程序输出结果为:姓名: 小白;年龄: 20
self.xxx=xxx的含义解释
class Person:
# 构造方法/构造器
def __init__(self, name, age):
print(f"姓名: {name};年龄: {age}")
# 把接收到的name和age赋给当前对象的属性
# self是当前创建的对象
self.name = name
self.age = age
print(f"self id: {id(self)}")
p1 = Person("小白", 20)
print(f"p1 id:{id(p1)}")
输出结果:
姓名: 小白;年龄: 20
self id: 1667972681160
p1 id:1667972681160
我们发现,self的地址与当前创建的对象的地址一样,则表明,self就是当前创建的对象p1。
如果此时再创建一个对象p2,那么程序该输出什么呢?程序如下所示。
class Person:
# 构造方法/构造器
def __init__(self, name, age):
print(f"姓名: {name};年龄: {age}")
# 把接收到的name和age赋给当前对象的属性
# self是当前创建的对象
self.name = name
self.age = age
print(f"self id: {id(self)}")
p1 = Person("小白", 20)
print(f"p1 id:{id(p1)}")
p2 = Person("小黑", 21)
print(f"p2 id:{id(p2)}")
程序输出结果为:
姓名: 小白;年龄: 20
self id: 1438208027976
p1 id:1438208027976
姓名: 小黑;年龄: 21
self id: 1438208028168
p2 id:1438208028168
根据上面的结果,这也验证了self 表示的就是当前对象。
3)一个类只有一个__init__方法,当有多个构造方法时,只有最后一个生效
class Person:
name = None
age = None
# 构造方法/构造器
def __init__(self, name, age):
print(f"姓名: {name};年龄: {age}")
# 把接收到的name和age赋给当前对象的属性
# self是当前创建的对象
self.name = name
self.age = age
def __init__(self, name):
print(f"姓名: {name}")
self.name = name
# p1 = Person("小白", 20) # 报错
# 后面的__init__方法生效
p1 = Person("Kobe")
print(f"p1的name={p1.name},age={p1.age}")
编译器验证
由上图可以得知,程序在第22行给出 Redeclared '__init__' defined above without usage 警告,意思是说,上面的__init__方法还没有使用,又重新声明了上面定义的__init__方法。
我们先来执行第27行代码,即 p1 = Person("小白", 20)这条语句 ,将后面的代码注释掉,然后运行程序,得到如下结果。
我们发现,程序会直接报错,错误的原因是,__init__()方法需要两个参数但是给了3个 ,也就是说,程序默认执行后一个__init__()方法。
注意,我们观察第27行代码,如下图所示,传入的参数明明只有两个编译器却为什么说传进去了3个呢?这是因为传入的参数为“小白”、20,还有一个参数是p1这个对象,它会隐式地传入。
接下来我们执行第30、31行代码,程序输出的结果为:
姓名: Kobe
p1的name=Kobe,age=None
这也能够说明程序默认选择最后一个__init__()方法进行执行。
4)在Python中实现多个构造方法,可参考下面这篇文章
https://www.cnblogs.com/kingwz/p/16335499.html
5)python可以动态的生成对象属性
通过__init__()方法动态的生成对象属性
在上述代码中,我们将Person类中的name属性和age属性注释掉,或者将这两个属性删除。第21、22行代码的作用是将接收到的name和age属性赋给当前对象的name和age属性,但我们已经将Person类中的name属性和age属性注释掉了,为什么程序执行时不报错呢?这是因为Python支持动态生成对象属性。
程序运行结果为:
p1的name=Kobe,age=20
6)构造方法不能有返回值(默认返回None)