65. Python
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
65. __init__
方法
文章目录
1. 知识回顾在类的方法中调用类的属性
【目标任务】
创建一个类计算2个数的和。
【体验代码】
# 定义一个求和类类名为Sum
class Sum:
# 直接写在类里的变量称为类属性
x = 2
y = 4
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum( )
# 调用对象对象名.方法名(值)
he.qiuhe( )
运行上述的代码程序报错提示name 'x' is not defined
即x没有被定义。
观察代码的第5和第6行我已经给变量赋值了。
# 直接写在类里的变量称为类属性
x = 2
y = 4
但程序还是提示没有被定义这是因为x
和y
是在类里定义的变量。
在类里定义的变量我们称之为类属性。
上节课我们学过在类内部的方法中调用类的属性或其它类的方法时需要在前面加上slef. 如
self.属性名
self.方法名
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self):
# 方法中的代码块
print(x+y)
qiuhe
是在类中定义的方法。
x和y是类里的属性。
要调用类里的属性语法为self.属性名。
因此我们将代码的第12行:
# 方法中的代码块
print(x+y)
更改如下
# 方法中的代码块
print(self.x+self.y)
【综合代码】
# 定义一个求和类类名为Sum
class Sum:
# 直接写在类里的变量称为类属性
x = 2
y = 4
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self):
# 方法中的代码块
print(self.x+self.y)
# 创建对象对象名=类名( )
he= Sum( )
# 调用对象对象名.方法名(值)
he.qiuhe()
【终端输出】
6
输出结果为6我们成功设计了一个求和的小程序。
但这个程序只能计算2和4的和不方便用户。
用户如果需要计算其他2个数的和就要更改类的属性。
我们使用类的优势之一在于代码写好后我们将它封装保存需要的时候我们直接调用它就好。
因此我们最好不要取修改类里的代码。
那怎么优化呢
我们可以通过调用方法时传值的形式进行代码优化。
2. 知识回顾调用方法时传值
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self,x,y):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum( )
# 调用对象对象名.方法名(值)
he.qiuhe(2,4)
【终端输出】
6
和之前的代码相比我做了如下改动
- 我把类定义属性的语句删除了。
# 直接写在类里的变量称为类属性
x = 2
y = 4
- 我修改了求和方法的参数。
将原来的
def qiuhe(self):
# 方法中的代码块
print(self.x+self.y)
修改为
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self,x,y):
# 方法中的代码块
print(x+y)
和之前的方法相比我在方法中增加了2个参数x和y。
最后再调用方法的时候直接传入方法中需要的值。
# 调用对象对象名.方法名(值)
he.qiuhe(2,4)
方法中的值是按位置进行传递的。
2传递给x。
4传递给y。
方法传值的优势在于不管你想计算哪两个数的和只需要修改方法中的值即可。
【体验代码】
观察下面的代码只用修改值我们就可成功计算出多个两位数的和。
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
# 方法名为qiuhe功能是计算类里2个变量的和
def qiuhe(self,x,y):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum( )
# 调用对象对象名.方法名(值)
he.qiuhe(2,4)
he.qiuhe(4,4)
he.qiuhe(7,4)
【终端输出】
6
8
11
3.体验__init__
方法
我们还可以继续优化我们的代码
观察下面的代码重点注意观察第6行。
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
# 方法名为__init__
def __init__(self,x,y):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum(2,4)
【终端输出】
6
上面的代码较之前的代码我做了如下几个调整
- 把之前的函数名
qiuhe
修改为__init__
下面是之前的旧代码
# 定义一个方法计算类里2个变量的和
def qiuhe(self,x,y):
# 方法中的代码块
print(x+y)
下面是修改后的代码
def __init__(self,x,y):
# 方法中的代码块
print(x+y)
- 把要传递的值放入创建对象的语句里删除了调用方法的代码。
之前的旧代码有调用方法语句传入的值在调用方法语句里。
# 创建对象对象名.类名( )
he= Sum( )
# 调用对象对象名.方法名(值)
he.qiuhe(2,4)
现在的代码只有创建对象语句传入的值在创建对象语句里。
# 创建对象对象名=类名(值)
he= Sum(2,4)
之前说过要输出类方法里的语句是需要一个调用方法的语句的。
那为什么这里修改方法名后不调用也能输出呢。
那是因为__init__
方法的作用就是在类创建对象时不需要调用方法语句就可以自动执行__init__
方法中的代码块这是我自己对该方法的解释仅供参考。
大家可以试一下同样的情况下如果方法名不为__init__
程序是会报错的
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
def qiuhe(self,x,y):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum(2,4)
【终端输出】
TypeError: Sum() takes no arguments
运行上述代码程序报错提示Sum() takes no arguments
即Sum不接受参数。
同样的代码方法名不一样输出结果就不一样这就是__init__
方法在作怪。
4. __init__
的作用
Python本身有内置函数和自定义函数两种。
自定义函数我们可以根据自己的喜好命名。
但内置函数就不能随便更改名字。只有单词拼写正确了我们才能使用该函数本身具有的功能。例如type、input、print函数。
其实类中也可以这样理解。
上节课我用的drive stopback都是我自己定义的方法名。
这里的 __init__
我们可以理解成它是类中的内置方法方法名是固定的。
init是initialization的缩写。
initialization [ɪˌnɪʃəlaɪ’zeɪʃn] 初始化。
__init__
方法通常称为初始化方法。
__init__
方法的作用官方解释是支持带参数类的初始化声明该类的属性类中的变量。
如果你是小白这样的话术很难理解。
那我们可以这样理解它
类中的属性不是一成不变的是一个可能会变化的值。
我们不想在类中定义属性而想在创建对象时传入这时可以用init方法在类中声明属性即类里的变量。
当然我还有一种简单粗暴的理解。
你就把它当做一个类中的普通方法这个方法有以下几个作用
1. init方法接收创建对象时传入的值。
2. init方法中的代码块不需要调用语句创建对象就会被自动执行。
【举例说明】
class Test:
def __init__ (self):
print("只要有创建对象语句我就会被输出。")
def A(self):
print("要调用方法A我才输出。")
# 创建对象对象名=类名( )
ceshi= Test( )
【终端输出】
只要有创建对象语句我就会被输出。
上述代码因为只有创建对象语句没有调用方法语句。
因此下面这个语句被输出了因为init方法中的代码块会自动被执行。
print("只要有创建对象语句我就会被输出。")
下面的语句没有输出因为没有调用方法A。
print("要调用方法A我才输出。")
【增加一个调用方法A的语句】
class Test:
def __init__ (self):
print("只要有创建对象语句我就会被输出")
def A(self):
print("要调用方法A我才输出。")
# 创建对象对象名=类名( )
ceshi= Test( )
# 调用方法对象名.方法名
ceshi.A()
【终端输出】
只要有创建对象语句我就会被输出
要调用方法A我才输出。
两句话都被输出了因为我增加了调用方法A的语句如下
# 调用方法对象名.方法名
ceshi.A()
5. __init__
方法的写法
定义__init__
方法的语法和定义其它方法的语法是一样的。
有两个需要特别注意的地方。
-
方法名是
init
很多初学者容易错写成int
。 -
方法名前后格有2条小横线注意是前面2条后面2条总的4条。初学者易写成2条小横线。
6. __init__
方法调用类的属性
这是我刚才写的代码
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
# 方法名为__init__
def __init__(self,x,y):
# 方法中的代码块
print(x+y)
# 创建对象对象名=类名( )
he= Sum(2,4)
上述的代码运行虽然没有错误但其实是不规范的。
下面的代码是规范的
# 定义一个求和类类名为Sum
class Sum:
# 在类中定义的函数称为方法
# 方法名为__init__
def __init__(self,x,y):
self.x = x
self.y = y
# 方法中的代码块
print(self.x+self.y)
# 创建对象对象名=类名( )
he= Sum(2,4)
【终端输出】
6
我是这样理解的仅供大家参考
2和4是在创建对象时传入的值理论上等同于类的属性。
是类的属性在类中调用类的属于就需要用self.属性名。
上述方法有self,x,y三个参数。
self.x
中的x表示的是类的属性。
等号后面的x表示的是值。
self.属性=值
self.x = x
self.y = y
按照位置2传递给x。self.x相当于类里的变量x。
按照位置4传递给y。self.y相当于类里的变量y。
按照语法规则在init中我们是要带着self
.走的。
但没有目前也没有报错。
至于为什么没报错或者self.
在这里存在的意义我目前还没有语言给大家解释清楚。
但建议所有学者都带上self.
我相信存在既有意义只是我水平不够解释不清楚。
7. 课堂实操
下面是我们上节课生产各种汽车的代码
# 定义一个车类类名为Cars
class Cars:
# 直接写在类里的变量称为类属性
color_1 = "红色"
color_2 = "黑色"
color_3 = "黄色"
color_4 = "绿色"
type_1 = "小轿车"
type_2 = "越野车"
type_3 = "公交车"
type_4 = "跑车"
# 在类中定义的函数称为方法
# 方法的第1个参数必须是slef
def drive(self, speed):
# 方法中的代码块
print(f"经测试{self.color_4}的{self.type_4}的最高时速是{speed}公里每小时。")
print("经测试{}的{}的最高时速是{}公里每小时。".format(self.color_2, self.type_4, speed))
print("经测试{}的{}的最高时速是{}公里每小时。".format(self.color_1, self.type_4, speed))
# 创建对象对象名=类名( )
paoche = Cars( )
# 调用对象对象名.方法名(值)
# 测试车速
paoche.drive(230)
【终端输出】
经测试绿色的跑车的最高时速是230公里每小时。
经测试黑色的跑车的最高时速是230公里每小时。
经测试红色的跑车的最高时速是230公里每小时。
下面我对上面的代码就行优化
# 定义一个车类类名为Cars
class Cars:
# 使用初始化方法init
def __init__(self, color, type, speed):
self.color = color
self.type = type
self.speed =speed
# 方法中的代码块
print(f"经测试{self.color}的{self.type}的最高时速是{self.speed}公里每小时。")
# 创建对象对象名=类名( )
che = Cars("红色","公交车",160 )
che = Cars("黑色","跑车",280 )
che = Cars("黄色","卡车",180 )
che = Cars("紫色","小轿车",240)
che = Cars("黑色","小轿车",240)
che = Cars("红色","小轿车",240)
che = Cars("绿色","小轿车",240)
【终端输出】
经测试红色的公交车的最高时速是160公里每小时。
经测试黑色的跑车的最高时速是280公里每小时。
经测试黄色的卡车的最高时速是180公里每小时。
经测试紫色的小轿车的最高时速是240公里每小时。
经测试黑色的小轿车的最高时速是240公里每小时。
经测试红色的小轿车的最高时速是240公里每小时。
经测试绿色的小轿车的最高时速是240公里每小时。
对比2段代码大家应该能感受到init方法的优势了。
终端输出了7个语句即生产了7种汽车。
如果我们没有用init方法要输出上面的这7个语句。
我们需要定义7个颜色变量7个汽车类型变量7个汽车时速变量写7带字符串格式化的输出语句。
而用init方法代码就相对简洁了很多。