引言:两种编程思维
【面向过程】——看重的是解决问题的过程,编程主要用到的是 “函数” 知识,将每个过程步骤打包成函数,再依次调用。
举例:
在3V3游戏中
【面向对象】——编程主要用到的是 “类和对象” 知识
举例:
我们直接面对的是机器人,而非炒菜的过程,所以这里机器人就是我们面对的对象
1、类是一个函数包
类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量。
1.1类中可以放置函数和变量
就像我们可以用def语句来自定义一个函数,我们用class语句来自定义一个类。
既然【类】是一个函数包,所以一个类中可以放置一堆函数,就像这样:
类中被定义的函数被称为类的【方法】,描述的是这个类能做什么。我们使用 类名.函数名() 的格式,就可以让类的方法运行起来。
class 类A():
def 函数1():
print('报道!我是类A的第一个方法!')
def 函数2():
print('报道!我是类A的第二个方法!')
def 函数3():
print('报道!我是类A的第三个方法!')
类A.函数1()
类A.函数2()
类A.函数3()
>>>
报道!我是类A的第一个方法!
报道!我是类A的第二个方法!
报道!我是类A的第三个方法!
除了函数外,在类中还可以放置一堆变量,就像这样:
在类中被定义的变量被称为类的【属性】,使用 类名.变量名 的格式,可以把类中的属性的值提取出来。
class 类A():
变量1 = 100
变量2 = -5.83
变量3 = 'abc'
# 这里需要用print语句,才能把提取出的数值打印到屏幕上
print(类A.变量1)
print(类A.变量2)
print(类A.变量3)
>>>
100
-5.83
abc
类中的属性(变量)可以改变,使用 类名.变量名 的格式,可以让我们 在类的外面 ,增加或修改类的属性:
class 类A():
变量1 = 100
变量2 = -5.83
变量3 = 'abc'
#需要在类的外部进行以下操作
类A.变量1 = 99
类A.变量2 = '你好'
#修改类的属性
类A.变量4 = '新增一个变量' #增加类的属性:
print(类A.变量1)
print(类A.变量2)
print(类A.变量4)
>>>
99
你好
新增一个变量
当类中放置了函数和变量,类就有了方法和属性。
下面我们来制作一个最简单的,既有方法又有属性的类:
class 智能机器人():
胸围 = 33
腰围 = 44
臀围 = 55
# 以上为类属性
def 打招呼():
print('主人你好!')
def 卖萌():
print('主人,求抱抱!')
def 生气():
print('主人,我要报警了!')
# 以上为类方法
智能机器人.打招呼()
智能机器人.卖萌()
智能机器人.生气()
#以上运行类的方法
print(智能机器人.胸围)
print(智能机器人.腰围)
print(智能机器人.臀围)
#以上用print提取属性
>>>
主人你好!
主人,求抱抱!
主人,我要报警了!
33
44
55
提示:我们为了让代码更直观, 一般会把类中的函数和函数之间换行隔开
类方法也是函数,与我们之前学的单独定义函数有什么区别吗?
最大区别:
(1)调用格式:类.函数名()比函数名()多了一个【类.】
(2)“类”中的函数可以利用“类”中的变量(也就是类方法可以调用类属性)。
1.2、类方法和类属性可以组合
class 类A():
变量1=100
变量2=200
@classmethod
def 函数1(cls):
print(cls.变量1)
print(cls.变量2)
类A.函数1()
>>>
100
200
在这里,为了把类中的变量传递给类中的函数,我们需要用到 3个特定格式:
(1)第一个格式@classmethod的中文意思就是“类方法”,@classmethod声明了函数1是类方法,这样才能允许函数1使用类属性中的数据。
(2)第二个格式cls的意思是class的缩写。
如果类方法1想使用类中的变量,就要写上cls为函数1的第一个参数,也就是把这个类作为参数传给自己,这样就能被允许使用类中的数据。
(3)第三个格式是cls.变量。类方法想使用类属性的时候,需要在这些变量名称前加上cls.。
另外,当类中的函数【不需要】用到类中的变量时,就不要用@classmethod、cls、cls.三处格式
class 类A():
变量1 = 100
变量2 = 20
def 函数1():
print('我不需要使用类属性')
类A.函数1()
>>>
我不需要使用类属性
练习:
为刚才的智能机器人,再写一个自报三围的类方法,调用方式是智能机器人.自报三围()
class 智能机器人():
胸围=33
腰围=44
臀围=55
@classmethod
def 自报三围(cls):
print('主人,我的三围是:')
print('胸围:'+str(cls.胸围))
print('腰围:'+str(cls.腰围))
print('臀围:'+str(cls.臀围))
print('哈哈哈哈哈,下面粗上面细,我长得像个圆锥。')
智能机器人.自报三围()
>>>
主人,我的三围是:
胸围:33
腰围:44
臀围:55
哈哈哈哈哈,下面粗上面细,我长得像个圆锥。
2、给类方法传参
2.1类方法仅使用外部参数
class 加100类():
def 加100函数(参数):
总和 = 参数 + 100
print('计算结果如下:')
print(总和)
参数 = 1 #外部参数
加100类.加100函数(参数)
>>>
计算结果如下:
1
这里的加100类()中的加100函数,只使用了外部的参数,没有使用类属性,所以格式上不需要@classmethod和cls
2.2类方法仅使用内部参数
练习1:
请你把上面的代码改造成类方法
(1)使用外部参数
class 念诗类():
def 念诗函数(参数):
for i in 参数:
print(i)
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
念诗函数(一首诗)
>>>
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
(2)使用内部参数
方法1
class 念诗类():
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
@classmethod
def 念诗函数(cls):
for i in range(5):
print(cls.一首诗[i])
念诗类.念诗函数()
方法2
class 念诗类():
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
@classmethod
def 念诗函数(cls):
for i in cls.一首诗:
print(i)
念诗类.念诗函数()
2.3类方法同时使用内部参数和外部参数
class 加100类():
变量 = 100
@classmethod
def 加100函数(cls,参数):
总和 = cls.变量 + 参数
print('加100函数计算结果如下:')
print(总和)
参数=int(input('请输入一个整数;'))
加100类.加100函数(参数)
#()里要有外部参数的参数名
>>>
请输入一个整数;23
加100函数计算结果如下:
123
当类方法要使用多个外部参数时,我们要多预设几个参数位置,比如:
class 加100类():
变量 = 100
@classmethod
def 加100函数(cls,参数1,参数2,参数3):
总和 = cls.变量 + 参数1 + 参数2 + 参数3
print('加100函数计算结果如下:')
print(总和)
参数1 = int(input('请输入一个整数:'))
参数2 = int(input('请输入一个整数:'))
参数3 = int(input('请输入一个整数:'))
加100类.加100函数(参数1,参数2,参数3)
练习2:改造这段念诗代码,让念诗类.念诗函数()可以接受外部参数
class 念诗类():
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
@classmethod
def 念诗函数(cls,参数):
print(参数)
print(type(cls.一首诗))
for i in cls.一首诗:
print(i)
参数='念给张三的诗:'
念诗类.念诗函数(参数)
>>>
念给张三的诗:
['《卜算子》', '我住长江头,', '君住长江尾。', '日日思君不见君,', '共饮长江水。']
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
3、增加/修改类属性
3.1从外部增加/修改属性
练习3:
变量1 = 15
#这是类外部的变量1
变量2 = 'abc'
class 类A():
变量1 = 100
#这是类属性变量1
变量1 = 类A.变量1
类A.变量2 = 变量2
#为类A增加了一个类属性变量2,它的值等于外部的变量2也就是abc。
print(类A.变量1)
print(类A.变量2)
>>>
100
abc
利用input函数从外部接收信息,并通过赋值的方式保存到类.变量
class 类():
@classmethod
def 打印类属性(cls):
print(cls.变量)
类.变量 = input('请输入字符串:')
#外部增加类变量
类.打印类属性()
>>>
请输入字符串:abc
abc
3.2从内部增加/修改属性
class 类():
@classmethod
def 增加类属性(cls):
cls.变量 = input('请输入字符串:')
#类方法内部直接增加属性
类.增加类属性()
print('打印新增的类属性:')
print(类.变量)
>>>
请输入字符串:123
打印新增的类属性:
123
练习2的升级版:
class 念诗类():
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
@classmethod
def 念诗函数(cls):
cls.接收人 = input('请输入你想给谁念诗:') #内部增加属性,接收外部信息(省去了参数)
print('念给'+ cls.接收人 +'的诗:')
for i in cls.一首诗:
print(i)
念诗类.念诗函数()
4、课堂实操
录入一张成绩单,把一个学生的姓名和成绩存起来
class 成绩单类():
@classmethod
def 成绩单函数(cls):
cls.姓名=input('请输入学生姓名:')
cls.语文成绩=int(input('请输入学生的语文成绩:'))
cls.数学成绩=int(input('请输入学生的数学成绩:'))
@classmethod
def 打印成绩单(cls):
print(cls.姓名+'的成绩单如下:')
print('语文成绩:',end='')
print(cls.语文成绩)
print('数学成绩:',end='')
print(cls.数学成绩)
@classmethod
def 打印平均分(cls):
cls.平均分=(cls.语文成绩+cls.数学成绩)/2
print(cls.姓名+'的平均分是:'+str(cls.平均分))
@classmethod
def 评级(cls):
if cls.平均分>=90:
print(cls.姓名+'的评级是:优')
elif 80<=cls.平均分<90:
print(cls.姓名+'的评级是:良')
elif 60<=cls.平均分<80:
print(cls.姓名+'的评级是:中')
else:
print(cls.姓名+'的评级是:差')
成绩单类.成绩单函数()
成绩单类.打印成绩单()
成绩单类.打印平均分()
成绩单类.评级()
>>>
请输入学生姓名:王明明
请输入学生的语文成绩:78
请输入学生的数学成绩:89
王明明的成绩单如下:
语文成绩:78
数学成绩:89
王明明的平均分是:83.5
王明明的评级是:良
另外再给大家展示一个编程技巧: 类方法不但能调用类属性,还能直接调用其他类方法。
①是调用类方法评级,②是在评级内部调用了类方法计算平均分,③④是类方法计算平均分的过程,最后返回的值重新赋值给了评级中的类属性平均分。
注意:
def 评级(cls)中的平均分和def 计算平均分(cls)的平均分,是两个不同的变量,因为它们在不同的函数下工作,作用域不同。
class 成绩单():
@classmethod
def 录入成绩单(cls):
cls.学生姓名 = input('请输入学生姓名:')
cls.成绩 = int(input('请输入考试成绩:'))
@classmethod
def 计算是否及格(cls):
if cls.成绩 >= 60:
return '及格'
else:
return '不及格'#return语句暂时保存数据
@classmethod
def 考试结果(cls):
#与其上面类的运行结果相关
if cls.计算是否及格()=='及格':
#注意if后的语句!!!!!
print(cls.学生姓名+'同学考试通过啦!')
else:
print(cls.学生姓名+'同学需要补考')
成绩单.录入成绩单()
成绩单.考试结果()
>>>
请输入学生姓名:王某
请输入考试成绩:45
王某同学需要补考