第二种方法是:制作一台炒菜机器人,然后告诉机器人做一道西红柿炒鸡蛋。
在这里,我们直接面对的是机器人,而非炒菜的过程,所以这里机器人就是我们面对的对象,这种解决问题的方法就叫做【面向对象】编程。
1 #直接运行即可 2 3 变量1 = 2019 4 变量2 = ‘中国梦‘ 5 6 def 打印变量(): 7 # 虽然可以中文命名,但括号依旧要用英文 8 print(变量1) 9 print(变量2) 10 11 def 两倍放大(数据): 12 数据 = 数据 * 2 13 return 数据 14 15 打印变量() 16 print(两倍放大(1000))
# 用英文取名才是规范的 var1 = 2019 var2 = ‘中国梦‘ def print_var(): print(var1) print(var2) def double_num(num): num = num * 2 return num print_var() print(double_num(1000))
输出
2019
中国梦
2000
类是一个函数包,理解【类】最简单的方式:【类】是一个函数包。类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量。
我们来看看类中是如何放置函数和变量的。
类中可以放置函数和变量
就像我们可以用def
语句来自定义一个函数,我们用class
语句来自定义一个类。
语法:创建一个名为“ClassName”的类,类名一般首字母要大写,(): 不能丢 class ClassName(): # 如定义一个名为‘狗‘的类,可以写成class Dog(): # 规范:class语句后续的代码块要缩进 def function1(): # 定义类中的函数1
既然【类】是一个函数包,所以一个类中可以放置一堆函数,就像这样:(如前文所说,以下例子会用中文取名)
class 类A(): def 函数1(): print(‘报道!我是类A的第一个方法!‘) def 函数2(): print(‘报道!我是类A的第二个方法!‘) def 函数3(): print(‘报道!我是类A的第三个方法!‘)
在类中被定义的函数被称为类的【方法】,描述的是这个类能做什么。我们使用类名.函数名()
的格式,就可以让类的方法运行起来。让我们来试一试:
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语句,把取出的数值打印到屏幕上)
class 类A(): 变量1 = 100 变量2 = -5.83 变量3 = ‘abc‘ # 这里需要用print语句,才能把提取出的数值打印到屏幕上 print(类A.变量1) print(类A.变量2) print(类A.变量3)
不过类中的属性(变量)也不是不能改变,使用类名.变量名
的格式,可以让我们在类的外面,增加或修改类的属性:
class 类A(): 变量1 = 100 变量2 = -5.83 变量3 = ‘abc‘ 类A.变量1 = 99 类A.变量4 = ‘新增一个变量‘ print(类A.变量1) print(类A.变量4)
当类中放置了函数和变量,类就有了方法和属性
下面我们来制作一个最简单的,既有方法又有属性的类:
class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 # 以上为类属性 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) # 以上为类方法
我们可以把类属性打印出来,也可以调用类方法。请运行代码体验一下这个“智能机器人”:
class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) print(‘把类的属性打印出来:‘) print(智能机器人.胸围) print(智能机器人.腰围) print(智能机器人.腰围) 智能机器人.打招呼() 智能机器人.卖萌() 智能机器人.生气()
现在你你应该知道使用类的属性和方法了吧?
下面我们来做个练习,请为机器人再添加一个方法智能机器人.奔跑()
,当运行这个方法的时候,屏幕上会打印出一串字符:我快乐地奔跑、奔跑……哎呦喂!撞墙了。
# 请补全代码 class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) def 奔跑(): print(‘我快乐的奔跑,奔跑,,,,,,,哎呦喂!撞墙了。‘) 智能机器人.奔跑()
再来做个练习,为机器人再添加一个属性智商 = 200
,当运行print(智能机器人.智商)
这个的时候,屏幕上会打印出200
。请补全代码。
class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 智商 = 200 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) print(智能机器人.智商)
干得不错哟~在这里,我们为了让代码更直观,一般会把类中的函数和函数之间换行隔开,这不影响代码运行。
看到这里,你可能会有有点疑惑,类方法也是函数,那和我们之前学的单独定义函数有什么区别吗?
们两者最大的区别,一个是它的调用格式:类.函数名()
比函数名()
多了一个【类.】,但更重要的是,“类”中的函数可以利用“类”中的变量(也就是类方法可以调用类属性)。
这里新出现的@classmethod
是声明了下面的函数是类方法,为什么要这么写呢?这就是我们接下来要讲的
类方法和类属性可以组合
什么意思呢?我们来看一个例子:下面的类中有两个变量和一个函数。请直接运行体验一下。然后请猜猜函数1
的功能是什么
# 请直接运行体验代码 class 类A(): 变量1 = 100 变量2 = 200 @classmethod def 函数1(cls): print(cls.变量1) print(cls.变量2) 类A.函数1()
函数1()
的功能是:把类中的变量1和变量2打印出来。
在这里,为了把类中的变量传递给类中的函数,我们需要用到3个特定格式:
① 第一个格式@classmethod
的中文意思就是“类方法”,@classmethod
声明了函数1
是类方法,这样才能允许函数1
使用类属性中的数据。
② 第二个格式cls
的意思是class
的缩写。如果类方法函数1
想使用类属性(也就是类中的变量),就要写上cls
为函数1
的第一个参数,也就是把这个类作为参数传给自己,这样就能被允许使用类中的数据。
③ 第三个格式是cls.变量
。类方法想使用类属性的时候,需要在这些变量名称前加上cls.
。
这就好比类方法
和类
之间的约法三章,所以但凡有任何格式错误都会报错。
另外,当类中的函数【不需要】用到类中的变量时,就不要用@classmethod
、cls
、cls.
三处格式,否则就是占着茅坑不拉屎,终端也会给你报错。(没错,就是这么傲娇~)
# 请运行代码,报错后,修改格式到正确的样式就能运行通过 class 类A(): 变量1 = 100 变量2 = 200 @classmethod def 函数1(): print(‘我不需要使用类属性。‘) 类A.函数1()
让我们牢记正确格式。当格式正确后,我们就可以开心的玩耍了
‘‘‘【正确案例】‘‘‘ class 类A(): 变量1 = 100 变量2 = 200 def 函数1(): # 【不需要】使用类属性 print(‘我不需要使用类属性。‘) @classmethod def 函数2(cls): # 【需要】使用类属性 print(cls.变量1) print(cls.变量2) 类A.函数1() 类A.函数2()
让我们做一个练习,为刚才的智能机器人,再写一个自报三围的类方法
,调用方式是智能机器人.自报三围()
,调用该类方法的终端显示效果如下:
主人,我的三围是: 胸围:33 腰围:44 臀围:55 哈哈哈哈哈,下面粗上面细,我长得像个圆锥
class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) def 自报三围 () print(‘主人,我的三围是:‘) 智能机器人.自报三围()
老师的答案是这样的:
# 请直接运行体验代码 class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 def 打招呼(): print(‘主人你好!‘) def 卖萌(): print(‘主人,求抱抱!‘) def 生气(): print(‘主人,我要报警了!‘) @classmethod def 自报三围(cls): print(‘主人,我的三围是:‘) print(‘胸围:‘ + str(cls.胸围)) print(‘腰围:‘ + str(cls.腰围)) print(‘臀围:‘ + str(cls.臀围)) print(‘哈哈哈哈哈,下面粗上面细,我长得像个圆锥。‘) 智能机器人.自报三围()
这个练习中,类方法
“自报三围”通过cls
的格式,取得了类属性
“胸围、腰围、臀围”的值并打印了出来。这个过程中,数据是按箭头方向流转的:
在实际编程中,通过【数据流转】,我们还能让类为我们做更多事情。
给类方法传参
首先,既然函数能传递参数,类方法能不能传递参数呢?答案是肯定的。我们谈一谈如何给类方法传参。
类方法仅使用外部参数
我们可以给函数传递参数被函数内部使用,就像这样:
def add_100(num): sum = num + 100 print(‘计算结果如下:‘) print(sum) num = 1 add_100(num)
计算结果如下:
101
类方法和函数类似,也可以传递参数。我们把上面的函数"收编",改造成类中的方法,代码会变成这样:
# 请直接运行并体验代码效果 class 加100类(): def 加100函数(参数): 总和 = 参数 + 100 print(‘计算结果如下:‘) print(总和) 参数 = 1 加100类.加100函数(参数)
这里的加100类()
中的加100函数
,只使用了外部的参数,没有使用类属性,所以格式上不需要@classmethod
和cls
。
让我们做个练习。这里有一个函数,运行起来可以“念诗”:
一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] def 念诗函数(参数): for i in 参数: print(i) 念诗函数(一首诗)
请你把上面的代码改造成类方法:
首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] class 念诗类(): def 念诗函数(参数): for i in 参数: print(i) 念诗类.念诗函数(一首诗)
和函数不同的是,类方法还可以利用类属性作为参数,也就是从类的内部给自己传递参数。
类方法仅使用内部参数
课堂开始的时候有一个智能机器人的例题,就是从类的内部给自己传递参数。我们运行代码体验一下:
# 请直接运行并体验代码效果 class 智能机器人(): 胸围 = 33 腰围 = 44 臀围 = 55 @classmethod def 自报三围(cls): print(‘主人,我的三围是:‘) print(‘胸围:‘ + str(cls.胸围)) print(‘腰围:‘ + str(cls.腰围)) print(‘臀围:‘ + str(cls.臀围)) print(‘哈哈哈哈哈,下面粗上面细,我长得像个圆锥。‘) 智能机器人.自报三围()
我们来做个练习,这是刚才的念诗类方法
一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] class 念诗类(): def 念诗函数(参数): for i in 参数: print(i) 念诗类.念诗函数(一首诗)
然后我们把变量一首诗
从类的外部放到类的内部,请你调整代码,让念诗类()
能够从内部获得参数,实现和之前相同的念诗功能。提示:可参考上述机器人的例子
class 念诗类(): 一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] @classmethod def 念诗函数(cls): for i in cls.一首诗: print(i) 念诗类.念诗函数()
当然,类方法可以同时使用内部参数和外部参数,我们接着看。
老师写了一个加100类
# 请直接运行并体验代码效果 class 加100类(): 变量 = 100 @classmethod def 加100函数(cls,参数): 总和 = cls.变量 + 参数 print(‘加100函数计算结果如下:‘) print(总和) 参数 = int(input(‘请输入一个整数:‘)) 加100类.加100函数(参数)
这个类一共接受了两个参数,一个是用户输入的外部参数,另一个是cls
这个内部参数
另外提一下,当类方法要使用多个外部参数时,我们要多预设几个参数位置。比如:
# 请直接运行并体验代码效果 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)
我们再做个练习吧~
你的目标是:改造这段念诗代码,让念诗类.念诗函数()
可以接受外部参数,且运行效果应如下:
念给张三的诗:
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
class 念诗类(): 一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] @classmethod def 念诗函数(cls,参数1): print(‘念给‘+参数1+‘的诗:‘) for i in cls.一首诗: print(i) 念诗类.念诗函数(‘张三‘)
到这里,给类方法传参的知识全部讲完了,让我们总结一下
接下来我们要讲解一下,如何增加/修改类属性。
有两种途径来增加或修改类属性。一种是从内部,用类方法
去增加/修改;另一种是从外部,用类.变量 = xx
直接增加/修改类属性。
从外部增加/修改属性
我们先看看从外部直接增加/修改类属性:
# 请直接运行并体验代码效果 class 类A(): pass 类A.变量1 = 100 print(类A.变量1)
类A()
是一个空类(里面的pass语句代表“什么都不做”),利用类A.变量1
,我们在外部给类A()
添加了一个类属性变量1
,然后使用print语句把类属性打印了出来。
我们来做个练习,请你观察以下代码,然后判断它的运行结果
变量1 = 15 #这是类外部的变量1 变量2 = ‘abc‘ class 类A(): 变量1 = 100 #这是类属性变量1 变量1 = 类A.变量1 类A.变量2 = 变量2 print(类A.变量1) print(类A.变量2)
变量1
和类属性变量1
是两个不同的变量。变量1 = 类A.变量1
是把类属性100重新赋值给了类外部的变量1,类属性变量1
的值没有改变,还是100。 而类A.变量2 = 变量2
,是为类A增加了一个类属性变量2
,它的值等于外部的变量2
也就是abc
我们再做一个练习。请你先体验以下代码,然后接下来会有一道题目。
# 请直接运行并体验代码效果 class 类(): @classmethod def 打印类属性(cls): print(cls.变量) 类.变量 = input(‘请输入字符串:‘) 类.打印类属性()
刚才你运行的代码,先利用input函数从外部接收了一个字符串,并通过赋值的方式保存为了类属性类.变量
。然后利用类方法类.打印类属性()
打印出了这个外部输入的字符串。
接下来,我们要做一个“幸运数翻倍”小程序,这个程序能接收外部输入的幸运数字,然后翻888倍打印出来。程序运行效果如下
你的幸运数是多少?请输入一个整数。(用户输入:66)
好的,我把它存了起来,然后翻了888倍还给你:58608
class 幸运(): @classmethod def 好运翻倍(cls): cls.a=str(cls.幸运数*888) print(‘好的,我把它存了起来,然后翻了888倍还给你:‘+cls.a) 幸运.幸运数 = int(input(‘你的幸运数是多少?请输入一个整数:‘)) 幸运.好运翻倍()
这是自己写的,老师写的如下
@classmethod
def 好运翻倍(cls):
print(‘好的,我把它存了起来,然后翻了888倍还给你:‘ + str(cls.幸运数*888))
# 或者这样写也可以:
# print(‘好的,我把它存了起来,然后翻了888倍还给你:%d‘ % (cls.幸运数*888))
幸运.好运翻倍()
到这里,如何从【类的外部】增加/修改类属性就比较清楚了,让我们再看看如何从【类的内部】增加/修改类属性
从内部增加/修改属性
我们来体验一段代码:让类方法直接增加/修改类属性:
# 请直接运行体验代码 class 类(): @classmethod def 增加类属性(cls): cls.变量 = input(‘请随意输入字符串:‘) 类.增加类属性() print(‘打印新增的类属性:‘) print(类.变量)
可以发现,我们直接通过类方法类.增加并打印类属性()
接收外部输入的字符串,然后新增为类属性
掌握这个技巧后,我们再做一个练习,这里是“给张三的诗”代码
class 念诗类(): 一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] @classmethod def 念诗函数(cls,参数): print(‘念给‘+ 参数 +‘的诗:‘) for i in cls.一首诗: print(i) 念诗类.念诗函数(‘张三‘)
现在希望你能改良这段程序,令它的运行效果如下:
请输入你想给谁念诗:(用户输入“张三”)
念给张三的诗:
《卜算子》
我住长江头,
君住长江尾。
日日思君不见君,
共饮长江水。
class 念诗类(): 一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] @classmethod def 念诗函数(cls): a = input(‘请输入你想给谁念诗:‘) print(‘念给‘+a+‘的诗‘) for i in cls.一首诗: print(i) 念诗类.念诗函数()
老师写的如下
class 念诗类(): 一首诗 = [‘《卜算子》‘,‘我住长江头,‘,‘君住长江尾。‘,‘日日思君不见君,‘,‘共饮长江水。‘] @classmethod def 念诗函数(cls): cls.接收人 = input(‘请输入你想给谁念诗:‘) print(‘念给‘+ cls.接收人 +‘的诗:‘) for i in cls.一首诗: print(i) 念诗类.念诗函数()
到这里,如何从类的内部和外部增加/修改类属性就学习完毕了:
现在是人人都会写代码的时代,作为班主任的你也不例外,为了录入学生的成绩,你自己写了一段代码:
# 请直接运行体验代码 class 成绩单(): @classmethod def 录入成绩单(cls): cls.学生姓名 = input(‘请输入学生姓名:‘) cls.语文_成绩 = int(input(‘请输入语文成绩:‘)) 成绩单.录入成绩单() print(成绩单.学生姓名 + ‘的成绩单如下:‘) print(‘语文成绩:‘+ str(成绩单.语文_成绩))
我们现在要做的第一步改装是,请写出一个类方法成绩单.打印成绩单()
,代替那两句print语句,起到同样的运行效果。
class 成绩单(): @classmethod def 录入成绩单(cls): cls.学生姓名 = input(‘请输入学生姓名:‘) cls.语文_成绩 = int(input(‘请输入语文成绩:‘)) @classmethod def 打印成绩单(cls): print(cls.学生姓名 + ‘的成绩单如下:‘) print(‘语文成绩:‘+ str(cls.语文_成绩)) 成绩单.录入成绩单() 成绩单.打印成绩单()
请继续改良class 成绩单()
,让它可以录入和打印的信息多一项“数学成绩”。要求改良后的代码运行效果是这样的:
class 成绩单(): @classmethod def 录入成绩单(cls): cls.学生姓名 = input(‘请输入学生姓名:‘) cls.语文_成绩 = int(input(‘请输入语文成绩:‘)) cls.数学_成绩= int(input(‘请输入数学成绩:‘)) @classmethod def 打印成绩单(cls): print(cls.学生姓名 + ‘的成绩单如下:‘) print(‘语文成绩:‘+ str(cls.语文_成绩)) print(‘数学成绩:‘+ str(cls.数学_成绩)) 成绩单.录入成绩单() 成绩单.打印成绩单()
让我们再接再厉,继续改良class 成绩单()
,让它多一个类方法成绩单.打印平均分()
。要求改良后的代码运行效果是这样的
class 成绩单(): @classmethod def 录入成绩单(cls): cls.学生姓名 = input(‘请输入学生姓名:‘) cls.语文_成绩 = int(input(‘请输入语文成绩:‘)) cls.数学_成绩 = int(input(‘请输入数学成绩:‘)) @classmethod def 打印成绩单(cls): print(cls.学生姓名 + ‘的成绩单如下:‘) print(‘语文成绩:‘+ str(cls.语文_成绩)) print(‘数学成绩:‘+ str(cls.数学_成绩)) @classmethod def 打印平均分(cls): print(int(cls.语文_成绩+cls.数学_成绩)/2) 成绩单.录入成绩单() 成绩单.打印成绩单() 成绩单.打印平均分()