你们的三连(点赞,收藏,评论)是我持续输出的动力,感谢。
在兴趣中学习,效益超乎想象,①有趣的源码与学习经验,②工具安装包,③专业解答,④学习资料共享
点击领取福利
入门Python- 一、python基础知识
- 1.第一个Python程序
- 1.1pycharm介绍
- 2.注释
- 2.1注释的作用
- 2.2注释的分类
- 3.变量和数据类型
- 4.Python基本数据类型
- 4.1整数
- 4.2浮点数
- 4.3复数
- 5.各种符号的意义及用法
- 5.1加减乘除(+- 我们都知道它们是什么含义了吧,就算你的数学是体育老师教的,你也会懂加减乘除吧。
不过有两个小细节值得你去注意,就是字符串之间的相加和相乘:
字符串之间的相加会被"拼接"起来,而字符串和数字相乘就会重复多次相同的字符串。
其它的大于、小于、大于等于、小于等于就不说了,因为我们小学老师都跟我们说过了。接下来说几个比较少见的符号。
5.2幂(**)幂就是以前我们学数学的时候老师讲的什么什么几次方,别一看到幂就想到杨幂。
用符号 ** 表示, 比如 2**3 = 8。
5.3整除(//)我们知道 / 是除的意思,你知道 6/3 等于多少么?你可能会觉得在侮辱你的智商对不对,不是 2 么? 在 python 中得出的结果是 2.0 , 也就是它返回的是浮点数。 那么我们只想得到整数部分怎么玩呢?
用 // 这个 : 6//3 = 2
5.4取模(%)取模的意思不是让你去获取个模特,是得到除法的余数,比如 8%5 = 3 ,因为 8/5 = 1余3。
5.5左移(<<)和右移(>>)移的意思就是把一个数的二进制移动多少个位。
比如 2 << 2 = 8 。
首先 2 的 二进制 是 0b00000010 ,然后将它左移2位(虚位补0)就变成这样: 0b00001000 ,它对应的十进制就是 8 。同样的道理:
8 >> 2 的意思就是将 8 的二进制向右移动2位:
0b00001000 右移动2位:0b00000010 也就是对应十进制的 2。
那么下次有人问你2*8怎么样写代码比较高效,你就直接甩给它: 2<<3 就好了。
5.6(&)记住一句话:“同真与真”,什么意思呢? 比如 1&1=1,1&0=0,
1就是真,0就是假。也就是只有 1&1=1,其它的都等于0。
那么 2 & 3 怎么算?
先将它们转化为二进制:
2对应的二进制 : 0b00000010
3对应的二进制 : 0b00000011
那么从右往左: 0&1=0 ,1&1=1,0&0=0,所以结果为
0b00000010,转化为十进制就是2,所以 2&3=2。
5.7(|)记住一句话:“同假或假”,什么意思呢? 比如 1|1=1,0|0=0,
1就是真,0就是假。也就是只有 0|0=0,其它的都等于1。
那么 2 | 3 怎么算?
先将它们转化为二进制:
2对应的二进制 : 0b00000010
3对应的二进制 : 0b00000011
那么从右往左: 0|1=1 ,1&1=1,0&0=0,所以结果为
0b00000011,转化为十进制就是3,所以 2|3=3。
5.8异或(^)相同者假,不同者真,什么意思呢?就是 1^1=0, 1^0=1。
那么 2^3 怎么算?
先将它们转化为二进制:
2对应的二进制 : 0b00000010
3对应的二进制 : 0b00000011
那么从右往左: 0^1=1 ,1^1=0,0&0=0,所以结果为
0b00000001,转化为十进制就是1,所以 2^3=1。
5.9翻转(~)x的按位翻转就是是-(x+1)。
那么 ~2 怎么算?
~2 = -(2+1) ; 所以答案就是-3。
ok,以上,其实没必要去记住,了解一下就这些符号是什么意思,怎么算的就好了。
二、Python中的循环语句 2.while循环while 活着: 每天做着一样的事情。这样写的意思就是,只要你活着,就一直不断的执行while下面的语句。
我们可以来写一个抛硬币的 python 程序,我们事先定义好硬币的正反面,然后让用户猜,如果用户猜对了就奖励一个吻,猜错了就继续猜,直到让他猜中为止。打开我们的 IDLE,代码敲起来:首先定义一个变量,我们的值定义为正面:
coin = "正面"
接着定义一个 flag :
flag = True
然后我们写一个循环:
while flag : guess = input("请猜一下是正面还是反面:") if(guess == "反面") : print("你猜错了,继续猜") elif(guess == "正面") : print("恭喜你猜对了,奖励你一个吻") flag = False执行:
解释一下:当 while 发现 flag 为 true 的时候,就会一次又一次的执行执行 while 下面的一句,直到我们猜中之后,我们就将flag 这个变量改为 false ,while 发现为 false 的时候就不往下循环了。
3.while循环的应用1.计算1~100的累积和(包含1和100)
i = 1 sum = 0 while i <= 100: sum += i i+=1 print(sum)
结果:
5050
4.for循环while 可以做到在条件为真的时候反复的执行,不过有时候我们需要在特定范围循环,比如说我们要在第一天到第五天每天做运动一次,那么这时候用 for 就再适合不过了:
days = [1,2,3,4,5] for day in days : print("第" + str(day) + "天做运动")day就是1,第二次day就是2,它就这样一直循环下去,没有一点念想。
5.终止循环break有一天你突然发现,我不能再这么下去了,不能再重复的过这样的日子了,得有点改变,跳出这个重复的怪圈,那么对于 Python 来说,用break:
while 活着: 重复的过日子。 if(醒悟): break通过 break 呢,就可以跳出这个循环了。
6.break和continue循环 6.1breakbreak 会立即终止循环,跳转到循环之后开始执行
结构:
while 条件: if 条件: break # 跳出循环举例:
i = 10 while i > 0: print("妈,还要我刷啊~~~~~~~~~") if i == 5: print('好了,不用刷了') break print("正在刷 %d 个碗" % i) i -= 1 print('程序结束')运行结果:
妈,还要我刷啊~~~~~~~~~ 正在刷 10 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 9 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 8 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 7 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 6 个碗 妈,还要我刷啊~~~~~~~~~ 好了,不用刷了 程序结束
6.2continuecontinue 会立即结束当前这一次循环,跳转到下一轮循环的条件判断
结构:
i = 10 while i > 0: print("妈,还要我刷啊~~~~~~~~~") if i == 5: print('好了,不用刷了') i -= 1 # continue 之前要注意修改 i 的值,否则容易导致死循环 continue print("正在刷 %d 个碗" % i) i -= 1 print('程序结束')运行结果:
妈,还要我刷啊~~~~~~~~~ 正在刷 10 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 9 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 8 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 7 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 6 个碗 妈,还要我刷啊~~~~~~~~~ 好了,不用刷了 妈,还要我刷啊~~~~~~~~~ 正在刷 4 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 3 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 2 个碗 妈,还要我刷啊~~~~~~~~~ 正在刷 1 个碗 程序结束
注意点:
- break/continue只能用在循环中,除此以外不能单独使用
- break/continue在嵌套循环中,只对最近的一层循环起作用
举例:
>>> # int(): 将数据转换为 int 类型 ... >>> str1 = "10" >>> # int() 默认按10进制转换后显示 ... num1 = int(str1) >>> >>> # int() 处理浮点数,只留下整数部分,舍弃小数部分(并不是四舍五入操作) ... num2 = int(3.74) >>> print(num2) 3 >>> >>> """ ... num1 = int(str1, 8) # 第二个参数为8,表示按8进制转换后显示,结果为 8 ... num1 = int(str1, 16) # # 第二个参数为16,表示按16进制转换后显示,结果为 16 ... #01 02 03 04 05 06 07 10 ... #01 02 ... 0B 0C 0D 0E 0F 10 ... print(num1) ... """ >>> >>> # float() 将数据转化为浮点数 ... str2 = "3.14" >>> f1 = float(str2) >>> print(type(f1))
>>> >>> f2 = float(10) >>> print(f2) 10.0 >>> >>> # complex() 创建复数: 第一个参数是复数的实部,第二个参数是复数的虚部 ... c1 = 10 + 4j >>> c2 = complex(10, 4) >>> >>> print(c1) (10+4j) >>> print(c2) # 等同与c1 (10+4j) >>> >>> # str() : 转换为 字符串类型 ... num1 = 10 >>> f1 = 3.14 >>> >>> print(type(str(num1))) >>> print(type(str(f1))) >>> >>> # repr(): 转换为表达式字符串 ... num1 = 10 >>> print(type(repr(num1))) >>> >>> >>> # eval(): 将字符串形式的数据,转换为原本的类型 ... str1 = "3.14" >>> print(type(eval(str1))) >>> >>> str2 = "[10, 20, 30]" >>> l = eval(str2) >>> print(type(l)) >>> >>> >>> # chr: 将一个整数转换为对应的 Unicode 字符 ... s = chr(1065) >>> print(s) Щ >>> >>> # ord :将一个字符转换为对应的字符编码数字 ... n = ord("A") >>> print(n) 65 >>> >>> # bin: 将一个整数转换为二进制 ... print(bin(1024)) # 0b 开头表示二进制数 0b10000000000 >>> >>> # oct:将一个整数转换为八进制 ... print(oct(1024)) # 0o 开头表示八进制数 0o2000 >>> >>> # hex: 将一个整数转换为十六进制 ... print(hex(1024)) # 0x 开头表示十六进制 0x400 >>> 附录:常用字符与ASCII码对照表
三、列表
1)什么是列表?
列表是用来存储大量数据的容器2)列表的格式
[value1,value2,value3,...]
注意:python列表中存储的数据可以是不同的数据类型
1.列表的常见操作 1.1增加元素 append结构:
mylist.append(values)
举例:
#定义变量A,默认有3个元素 A = ['xiaoWang','xiaoZhang','xiaoHua'] print("-----添加之前,列表A的数据-----") for tempName in A: print(tempName) #提示、并添加元素 temp = input('请输入要添加的学生姓名:') A.append(temp) print("-----添加之后,列表A的数据-----") for tempName in A: print(tempName)运行结果
-----添加之前,列表A的数据----- xiaoWang xiaoZhang xiaoHua 请输入要添加的学生姓名:哈哈 -----添加之后,列表A的数据----- xiaoWang xiaoZhang xiaoHua 哈哈
insert(向列表中指定位置插入数据)结构:
mylist.insert(index, object) 在指定位置index前插入元素object
举例:
>>> a = [0, 1, 2] >>> a.insert(1, 3) >>> a [0, 3, 1, 2]
extend(通过extend可以将另一个集合中的元素逐一添加到列表中)
结构:
myslist.extend(index,list)在指定位置index前插入列表
举例:
>>> a = [1, 2] >>> b = [3, 4] >>> a.append(b) >>> a [1, 2, [3, 4]] >>> a.extend(b) >>> a [1, 2, [3, 4], 3, 4]
1.2删除元素 del(根据下标进行删除)结构:
del mylist(index) # 删除mylist中index位置的元素
举例:
movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情'] print('------删除之前------') for tempName in movieName: print(tempName) del movieName[2] print('------删除之后------') for tempName in movieName: print(tempName)运行结果:
------删除之前------ 加勒比海盗 骇客帝国 第一滴血 指环王 霍比特人 速度与激情 ------删除之后------ 加勒比海盗 骇客帝国 指环王 霍比特人 速度与激情
pop(删除最后一个元素)结构:
list.pop()
举例:
movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情'] print('------删除之前------') for tempName in movieName: print(tempName) movieName.pop() print('------删除之后------') for tempName in movieName: print(tempName)运行结果:
------删除之前------ 加勒比海盗 骇客帝国 第一滴血 指环王 霍比特人 速度与激情 ------删除之后------ 加勒比海盗 骇客帝国 第一滴血 指环王 霍比特人
remove(根据元素的值进行删除)结构:
mylist.remove(value) # value 是mylist中的值
举例:
movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情'] print('------删除之前------') for tempName in movieName: print(tempName) movieName.remove('指环王') print('------删除之后------') for tempName in movieName: print(tempName)运行结果:
------删除之前------ 加勒比海盗 骇客帝国 第一滴血 指环王 霍比特人 速度与激情 ------删除之后------ 加勒比海盗 骇客帝国 第一滴血 霍比特人 速度与激情
1.3修改元素修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改
结构:
mylist[index] = newValue
举例:
# 定义变量A,默认有3个元素 A = ['xiaoWang', 'xiaoZhang', 'xiaoHua'] print("-----修改之前,列表A的数据-----") for tempName in A: print(tempName) # 修改元素 A[1] = 'xiaoLu' print("-----修改之后,列表A的数据-----") for tempName in A: print(tempName)运行结果:
-----修改之前,列表A的数据----- xiaoWang xiaoZhang xiaoHua -----修改之后,列表A的数据----- xiaoWang xiaoLu xiaoHua
1.4查看元素 in, not inpython中查找的常用方法为:
- in(存在),如果存在那么结果为true,否则为false
- not in(不存在),如果不存在那么结果为true,否则false
例如:
#待查找的列表 nameList = ['xiaoWang','xiaoZhang','xiaoHua'] #获取用户要查找的名字 findName = input('请输入要查找的姓名:') #查找是否存在 if findName in nameList: print('在字典中找到了相同的名字') else: print('没有找到')运行结果1:(找到)
请输入要查找的姓名:xiaoWang 在字典中找到了相同的名字
运行结果2:(没有找到)
请输入要查找的姓名:xiaoli 没有找到
说明:
index, countin的方法只要会用了,那么not in也是同样的用法,只不过not in判断的是不存在
index和count与字符串中的用法相同
>>> a = ['a', 'b', 'c', 'a', 'b'] >>> a.index('a', 1, 3) # 注意是左闭右开区间 Traceback (most recent call last): File "2.元组", line 1, in ValueError: 'a' is not in list >>> a.index('a', 1, 4) 3 >>> a.count('b') 2 >>> a.count('d') 0 其实元组和列表是差不多的,不过它们有一点区别就是:元组是不可变的数据类型,也就是说元组里面的内容是不能进行修改,删除,添加等操作的。
元组使用圆括号来表示,例如:avlist = ('亚洲无码原创区' ,'亚洲有码原创区' ,'欧美原创区' ,'动漫原创区' )
2.1查看元组元素
元组通常被用来打印语句:
举例:
mylist = ('123',1,"hhh") print(mylist[0])运行结果:
'123'
2.2修改元组中的元素例如:
mylist = ('123',1,"hhh") mylist[0] = "lisi" print(mylist)运行结果:
('lisi',1,'hhh')2.3count, indexindex和count与字符串和列表中的用法相同
>>> a = ('a', 'b', 'c', 'a', 'b') >>> a.index('a', 1, 3) # 注意是左闭右开区间 Traceback (most recent call last): File "3.字符串", line 1, in ValueError: tuple.index(x): x not in tuple >>> a.index('a', 1, 4) 3 >>> a.count('b') 2 >>> a.count('d') 0 1)字符串介绍
被一对双引号或者单引号包裹的数据就是字符串2)字符串输入
之前在学习input的时候,通过它能够完成从键盘获取数据,然后保存到指定的变量中;注意:input获取的数据,都以字符串的方式进行保存,即使输入的是数字,那么也是以字符串方式保存
3.1下标和切片下标/索引
“下标”又叫“索引”,就是编号。字符串中"下标"的使用
如果有字符串:name = 'abcdef',在内存中的实际存储如下:如果想取出部分字符,那么可以通过下标的方法,(注意python中下标从 0 开始)
name = 'abcdef' print(name[0]) print(name[1]) print(name[2])
运行结果:
a b c
3.2切片切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。
切片的语法:[起始:结束:步长]
注意:选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔。我们以字符串为例讲解。
如果取出一部分,则可以在中括号[]中,使用:
name = 'abcdef' print(name[0:3]) # 取 下标0~2 的字符
abc
4.字典 4.1什么是字典?由键-值对组成的数据
结构:
{key:value}说明:
- 字典和列表一样,也能够存储多个数据
- 列表中找某个元素时,是根据下标进行的
- 字典中找某个元素时,是根据key
- 字典的每个元素由2部分组成,键:值。
- 字典中若访问不存在的键,则会报错
- 使用字典名.get(key)若访问不存在的键不会报错会返回none
如果在使用 变量名[‘键’] = 数据 时,这个“键”在字典中,不存在,那么就会新增这个元素
举例:
info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'} # print('id为:%d'%info['id'])#程序会终端运行,因为访问了不存在的键 newId = int(input('请输入新的学号')) info['id'] = newId print('添加之后的id为:%d'%info['id'])运行结果:
请输入新的学号188 添加之后的id为: 188删del 删除指定的元素
结构:
del mydic[key]
例子:
info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'} print('删除前,%s'%info['name']) del info['name'] print('删除后,%s'%info['name']) ## 删除后不能访问会报错运行结果:
KeyError: 'name' 删除前,班长
clear() 清空整个字典
结构:
mydic.clear() demo: info = {'name':'monitor', 'sex':'f', 'address':'China'} print('清空前,%s'%info) info.clear() print('清空后,%s'%info)运行结果:
{}改字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改
例子:
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'} newId = input('请输入新的学号') info['id'] = int(newId) print('修改之后的id为:%d'%info['id'])运行结果:
请输入新的学号12 修改之后的id为:12
查除了使用key查找数据,还可以使用get来获取数据
结构
mydict[key] # 方法一 mydict.get(key)
例子:
info = {'name':'吴彦祖','age':18} print(info['age']) # 获取年龄 # print(info['sex']) # 获取不存在的key,会发生异常 print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常运行结果:
18 None
四、函数 1.函数介绍 1.1什么是函数?如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数
1.2函数定义和调用函数定义
定义函数的结构:def 函数名: 代码举例:
# 定义一个函数,能够完成打印信息的功能 def printInfo(): print('------------------------------------') print(' 人生苦短,我用Python') print('------------------------------------')调用函数
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,调用函数的结构
函数名()
举例:
# 定义完函数后,函数是不会自动执行的,需要调用它才可以 printInfo()
1.3函数的文档说明>>> def test(a,b): ... "用来完成对2个数求和" ... print("%d"%(a+b)) ... >>> >>> test(11,22) 33如果执行,以下代码
>>> help(test)
能够看到test函数的相关说明
Help on function test in module __main__: test(a, b) 用来完成对2个数求和 (END)小结:
在函数定义之后在函数定义后的那行添加上对函数的注释,使用help函数就可以直接打印函数的注释和函数名
2.函数的参数 2.1什么是函数的参数?所谓函数的参数就是在定义函数的时候可以让函数接收数据
2.2带参数函数的定义结构:
def 函数名(参数名): 代码(代码中可以使用参数)举例:
def add2num(a, b): c = a+b print(c)2.3带参数函数的调用结构1:
函数名(参数名=数据)
结构2:
函数名(数据) # 必须是参数名有几个数据就有几个,且位置对应
举例:
add2num(a=1,b=2) # add2num(1,2)
2.4调用函数的顺序>>> def test(a,b): ... print(a,b) ... >>> test(1,2) 1 2 >>> test(b=1,a=2) 2 1 >>> >>> test(b=1,2) File "
2.5缺省参数", line 1 SyntaxError: positional argument follows keyword argument >>> >>> 调用函数时,缺省参数的值如果没有传入,则取默认值
def printinfo(name, age=35): # 打印任何传入的字符串 print("name: %s" % name) print("age %d" % age) # 调用printinfo函数 printinfo(name="miki") # 在函数执行过程中 age去默认值35 printinfo(age=9 ,name="miki")运行结果:
name:miki age:35 name:miki age:9
总结:
- 形参中默认有值的参数,称之为缺省参数
- 注意:带有默认值的参数一定要位于参数列表的最后面
基本语法:
def 函数名(形参,*形参,**形参): 执行功能 return 返回值def fun(a, b, *args, **kwargs): """可变参数演示示例""" print("a =%d" % a) print("b =%d" % b) print("args:") print(args) print("kwargs: ") for key, value in kwargs.items(): #遍历字典 print("key=%s" % value) #输出字典 fun(1,2,3,4,5,m=6,n=7,p=8)#调用函数运行结果:
a = 1 b = 2 args = [3,4,5] kwargs = {"m":6,"n":7,"p":8}注意:
- 加了星号(*)的形参会存放所有未命名的变量参数,*形参为元组
- **而加*的形参会存放命名参数,即形如key=value的参数,*形参为字典.
- 定义时小括号中的参数,用来接收参数用的,称为 “形参”
- 调用时小括号中的参数,用来传递给函数用的,称为 “实参”
1)缺省参数
结构:def 函数名(参数名称=值): # 参数名称=值这种就是缺省参数 代码- 意义:缺省参数就是形参中默认有值的参数
- 注意:带有默认值的参数一定要位于参数列表的最后面
- 作用:调用函数时,缺省参数的值如果没有传入,则取默认值
举例:
def printinfo(name, age=35): # 打印任何传入的字符串 print("name: %s" % name) print("age %d" % age) # 调用printinfo函数 printinfo(name="miki") # 在函数执行过程中 age去默认值35 printinfo(age=9 ,name="miki")运行结果:
name: miki age: 35 name: miki age: 9
2)不定长参数
结构:def 函数名([formal_args,] *args, **kwargs): # *args, **kwargs就是不定长参数 """函数_文档字符串""" 代码 return [expression]
意义:有时可能需要一个函数能处理比当初声明时更多的参数, 这些参数叫做不定长参数,声明时不会命名。
注意:
- 加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
- 而加的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典
作用:可以接受不定的数据
举例:
def func(a, b, *args, **kwargs): """可变参数演示示例""" print("a=%s" % a) print("b=%s" % b) print("args:", end="") print(args) print("kwargs:", end="") for key, value in kwargs.items(): print("key=%s," % key, end="") print("value=%s" % value, end="n") # 注意参数对应 func(1, 2, 3, 4, 5, m=6, n=7, p=8) print("---------------------------") c = (3, 4, 5) d = {"m": 6, "n": 7, "p": 8} # 注意元组和字典的传参方式 func(1, 2, *c, **d) print("---------------------------") # 不加*比较 func(1, 2, c, d)运行结果:
a=1 b=2 args:(3, 4, 5) kwargs:key=m,value=6 key=n,value=7 key=p,value=8 --------------------------- a=1 b=2 args:(3, 4, 5) kwargs:key=m,value=6 key=n,value=7 key=p,value=8 --------------------------- a=1 b=2 args:((3, 4, 5), {'m': 6, 'n': 7, 'p': 8}) kwargs:3)缺省参数在*args后
如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的例子:
def sum_nums_3(a, *args, b=22, c=33, **kwargs): print(a) print(b) print(c) print(args) print(kwargs) sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)运行结果:
100 1 2 (200, 300, 400, 500, 600, 700) {'mm': 800, 'nn': 900}4.函数的返回值 4.1什么是函数返回值?所谓“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果
**1)**带有返回值的函数
结构:def 函数名(参数名/无参数名): “”“注释”“” 代码 return 返回值举例:
def add2num(a, b): c = a+b return c4.2保存函数的返回值所谓的保存其实就是将返回值给予给一个新的变量
举例:
#定义函数 def add2num(a, b): return a+b #调用函数,顺便保存函数的返回值 result = add2num(100,98) #因为result已经保存了add2num的返回值,所以接下来就可以使用了 print(result)结果:
198
4.3返回多个值关于return:一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处
返回多值的方法:return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据
注意:
return后面有多个数据,那么默认是元组
例如:
def divid(a, b): shang = a//b yushu = a%b return shang, yushu #默认是元组 result = divid(5, 2) print(result) # 输出(2, 1)5.函数的类型 5.1 4种函数的类型函数根据有没有参数,有没有返回值,可以相互组合,一共有4种
- 无参数,无返回值
- 无参数,有返回值
- 有参数,无返回值
- 有参数,有返回值
此类函数,不能接收参数,也没有返回值,一般情况下,打印提示灯类似的功能,使用这类的函数
def printMenu(): print('--------------------------') print(' xx涮涮锅 点菜系统') print('') print(' 1. 羊肉涮涮锅') print(' 2. 牛肉涮涮锅') print(' 3. 猪肉涮涮锅') print('--------------------------')结果:
-------------------------- xx涮涮锅 点菜系统 1. 羊肉涮涮锅 2. 牛肉涮涮锅 3. 猪肉涮涮锅 --------------------------5.3无参数,有返回值的函数此类函数,不能接收参数,但是可以返回某个数据,一般情况下,像采集数据,用此类函数
# 获取温度 def getTemperature(): # 这里是获取温度的一些处理过程 # 为了简单起见,先模拟返回一个数据 return 24 temperature = getTemperature() print('当前的温度为:%d'%temperature)结果:
当前的温度为: 24
5.4有参数,无返回值的函数此类函数,能接收参数,但不可以返回数据,一般情况下,对某些变量设置数据而不需结果时,用此类函数
5.5有参数,有返回值的函数此类函数,不仅能接收参数,还可以返回某个数据,一般情况下,像数据处理并需要结果的应用,用此类函数
# 计算1~num的累积和 def calculateNum(num): result = 0 i = 1 while i<=num: result = result + i i+=1 return result result = calculateNum(100) print('1~100的累积和为:%d'%result)结果:
1~100的累积和为: 5050
5.小总结
- 函数根据有没有参数,有没有返回值可以相互组合
- 定义函数时,是根据实际的功能需求来设计的,所以不同开发人员编写的函数类型各不相同
def testB(): print('---- testB start----') print('这里是testB函数执行的代码...(省略)...') print('---- testB end----') def testA(): print('---- testA start----') testB() print('---- testA end----') testA()结果:
---- testA start---- ---- testB start---- 这里是testB函数执行的代码...(省略)... ---- testB end---- ---- testA end----
小总结:-
一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用 函数嵌套调用
-
如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置
所谓的作用域是指有效的作用空间,在程序中是指某个变量或者数据作用的地方大小
7.2局部变量结构:
def 函数名(参数): 变量名称 # 这个变量就是局部变量- 意义:就是在函数内部定义的变量,其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
- 作用:局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储
- 有效时间:当函数调用时,局部变量被创建,当函数调用完成后这个变量就不能够使用了
结构:
变量名称 # 这个变量就是全局变量 def 函数(参数): 代码- 意义:在函数外边定义的变量,其作用范围是所有函数,所有的函数中都可以进行访问
- 作用:可以作为共享变量来使用
- 有效时间:直到程序结束
举例:
# 定义全局变量 a = 100 def test1(): a = 300 # 定义局部变量 print('-----test1----修改前---a=%d' % a) a = 200 print('-----test1----修改后---a=%d' % a) def test2(): print('-----test2---a=%d' % a) # 调用函数 test1() test2()运行结果:
-----test1----修改前---a=300 -----test1----修改后---a=200 -----test2---a=100
总结:当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值
7.5修改全局变量结构:
变量名称 # 定义全局变量 def 函数名(参数): global 变量名称 # 声明使用的是全局变量 代码
举例:
# 全局变量和局部变量名称相同例子 # 定义全局变量 a = 100 def test1(): global a # 声明全局变量 print('-----test1----修改前---a=%d' % a) a = 200 print('-----test1----修改后---a=%d' % a) def test2(): print('-----test2---a=%d' % a) # 调用函数 test1() test2()运行结果:
-----test1----修改前---a=100 -----test1----修改后---a=200 -----test2---a=200
总结:- 如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据也理解为对全局变量进行修改,而不是定义局部变量
- 如果在一个函数中需要对多个全局变量进行修改,那么可以使用
# 可以使用一次global对多个全局变量进行声明 global a, b # 还可以用多次global声明都是可以的 # global a # global b
8.函数的特性 8.1函数之间共享数据函数之间共享数据的方法如下:
1)使用全局变量举例:
g_num = 0 def test1(): global g_num # 将处理结果存储到全局变量g_num中 g_num = 100 def test2(): # 通过获取全局变量g_num的值,从而获得test1函数处理之后的结果 print(g_num) # 1.先调用test1得到数据保存到全局变量中 test1() # 2.在调用test2,处理test1函数执行之后的这个值 test2()运行结果:
100
函数之间共享变量可以使用全局变量作为媒介来存储和转发数据从而达到共享数据的结果
2)使用函数的返回值、参数举例:
def test1(): # 通过return将一个数据结果返回 return 50 def test2(num): # 通过形参的方式保存传递过来的数据,就可以处理了 print(num) # 1. 先调用test1得到数据并且存到变量result中 result = test1() # 2. 调用test2时,将result的值传递到test2中,从而让这个函数对其进行处理 test2(result)运行结果:
50
3)函数嵌套调用举例:
def test1(): # 通过return将一个数据结果返回 return 20 def test2(): # 1. 先调用test1并且把结果返回来 result = test1() # 2. 对result进行处理 print(result) # 调用test2时,完成所有的处理 test2()运行结果:
20
9.函数特殊化处理 9.1拆包所谓的拆包就是将python特殊结构的数据直接分开存储的过程
举例:
# 直接对函数的返回值进行拆包 def get_my_info(): high = 178 weight = 100 age = 18 return high, weight, age my_high, my_weight, my_age = get_my_info() print(my_high) print(my_weight) print(my_age)运行结果:
178 100 18
注意:
- 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
- 除了对元组拆包之外,还可以对列表、字典等拆包
举例:
In [17]: a, b = (11, 22) In [18]: a Out[18]: 11 In [19]: b Out[19]: 22 In [20]: a, b = [11, 22] In [21]: a Out[21]: 11 In [22]: b Out[22]: 22 In [23]: a, b = {"m":11, "n":22} # 取出来的是key,而不是键值对 In [24]: a Out[24]: 'm' In [25]: b Out[25]: 'n'9.2交换变量值交换变量的方法有很多
方法一:借用第三方帮助
举例:
a = 4 b = 5 c = 0 # 第三方 # 交换开始 c = a a = b b = c print(a) print(b)
方法二:计算法
举例:
a = 4 b = 5 # 开始计算 a = a+b # a=9, b=5 b = a-b # a=9, b=4 a = a-b # a=5, b=4 print(a) print(b)
方法三:拆包法
举例:
a, b = 4, 5 a, b = b, a print(a) print(b)
五、面向对象编程介绍 1.什么是面向对象?生活中我们用洗衣机洗衣服不比考虑洗衣机的构造和制造我们只需要直接把衣服丢进去即可,这种让其他专业的事物去做的思想就是面向对象,每一步我们都不需要亲力亲为,只需要关注结果就行。在编程中面向对象编程思想将数据与函数绑定到一起,分类进行封装,每个程序员只要负责分配给自己的分类,这样能够更快速的开发程序,减少了重复代码。
2.面向过程和面向对象对比面向过程:根据业务逻辑从上到下写代码,每一步都是自己做。
面向对象:将数据与函数绑定到一起,分类进行封装,每个程序员只要负责分配给自己的分类,这样能够更快速的开发程序,减少了重复代码,每一步都照专业的人做
面向对象(object-oriented ;简称: OO) 至今还没有统一的概念 我这里把它定义为: 按人们 认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。
面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件系统中相近相似的操作逻辑和操作 应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。
3.类和对象面向对象编程的2个非常重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象
3.1类概念:
- 具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
- 具有相同属性和行为事物的统称
类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象
概念:
- 某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。
- 可以是直接使用的
类和对象的关系好比就是做饼的模子和饼之间的关系,通过模子来制造饼。类就是创建对象的模板
3.4类的构成类(Class) 由3个部分构成
- 类的名称:类名
- 类的属性(就是变量):一组数据
- 类的方法(就是函数):允许对进行操作的方法 (行为)
举例:
# 猫类 类名:猫(cat) 属性:品种 、毛色、性别、名字、 腿儿的数量 方法(行为/功能):叫 、跑、吃、摇尾巴
3.5类的抽象如何把日常生活中的事物抽象成程序中的类?
拥有相同(或者类似)属性和行为的对象都可以抽像出一个类
方法:一般名词都是类(名词提炼法)
Eg:
小明正在使用电脑编程 小明 -->可以抽像成人类 电脑 -->可以抽像成电脑类
4.类的定义和对象的创建 4.1类的定义格式:
class 类名称: 方法列表举例:
# class Hero: # 经典类(旧式类)定义形式 # 定义一个英雄类 class Hero(object): def info(self): print("英雄莫问出处")说明:
- 定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;
- object 是Python 里所有类的最顶级父类;
- 类名 的命名规则按照"大驼峰命名法";
- info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量这个变量指向了实例对象
详细格式:
class 类名(object): def 方法1(self,参数列表) # 必须是self pass def 方法2(self,参数列表) pass4.2创建对象python中,可以根据已经定义的类去创建出一个或多个对象。
格式:
对象名 = 类名()
举例:
class Hero(object): def info(self): """info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self""" print(self) """当对象调用实例方法时,Python会自动将对象本身的引用做为参数,传递到实例方法的第一个参数self里""" print("self各不同,对象是出处") # Hero这个类 实例化了一个对象 super_man = Hero() # 对象调用实例方法info(),执行info()里的代码 # . 表示选择属性或者方法 super_man.info() print(super_man) # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self) print(id(super_man)) # id(super_man)则是内存地址的十进制形式表示4.3添加和获取对象的属性class Hero(object): """定义了一个英雄类,可以移动和攻击""" def move(self): """实例方法""" print("正在前往事发地点...") def attack(self): """实例方法""" print("发出了一招强力的普通攻击...") # 实例化了一个英雄对象 泰达米尔 taidamier = Hero() # 给对象添加属性,以及对应的属性值 taidamier.name = "泰达米尔" # 姓名 taidamier.hp = 2600 # 生命值 taidamier.atk = 450 # 攻击力 taidamier.armor = 200 # 护甲值 # 通过.成员选择运算符,获取对象的属性值 print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp)) print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk)) print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor)) # 通过.成员选择运算符,获取对象的实例方法 taidamier.move() taidamier.attack()4.4在方法内通过self获取对象属性class Hero(object): """定义了一个英雄类,可以移动和攻击""" def move(self): """实例方法""" print("正在前往事发地点...") def attack(self): """实例方法""" print("发出了一招强力的普通攻击...") def info(self): """在类的实例方法中,通过self获取该对象的属性""" print("英雄 %s 的生命值 :%d" % (self.name, self.hp)) print("英雄 %s 的攻击力 :%d" % (self.name, self.atk)) print("英雄 %s 的护甲值 :%d" % (self.name, self.armor)) # 实例化了一个英雄对象 泰达米尔 taidamier = Hero() # 给对象添加属性,以及对应的属性值 taidamier.name = "泰达米尔" # 姓名 taidamier.hp = 2600 # 生命值 taidamier.atk = 450 # 攻击力 taidamier.armor = 200 # 护甲值 # 通过.成员选择运算符,获取对象的实例方法 taidamier.info() # 只需要调用实例方法info(),即可获取英雄的属性 taidamier.move() taidamier.attack()5. init()方法 5.1魔法方法所谓的魔法方法是在python类里提供的,两个下划线开始,两个下划线结束的方法。
5.2什么是_init_()方法init()就是一个魔法方法,通常用来做属性初始化 或 赋值 操作。 如果类面没有写__init__方法,Python会自动创建,但是不执行任何操作,如果为了能够在完成自己想要的功能,可以自己定义__init__方法, 所以一个类里无论自己是否编写__init__方法一定有__init__方法。
结构:
class 类名称(object): def __init__(self): 属性/赋值举例:
class Hero(object): """定义了一个英雄类,可以移动和攻击""" def __init__(self): """ 方法,用来做变量初始化 或 赋值 操作,在类实例化对象的时候,会被自动调用""" self.name = "泰达米尔" # 姓名 self.hp = 2600 # 生命值 self.atk = 450 # 攻击力 self.armor = 200 # 护甲值 def move(self): """实例方法""" print("正在前往事发地点...") def attack(self): """实例方法""" print("发出了一招强力的普通攻击...") # 实例化了一个英雄对象,并自动调用__init__()方法 taidamier = Hero() # 通过.成员选择运算符,获取对象的实例方法 taidamier.info() # 只需要调用实例方法info(),即可获取英雄的属性 taidamier.move() taidamier.attack()说明:
- init()方法,在创建一个对象时默认被调用,不需要手动调用
- init(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。
结构:
class 类名称(object): def __init__(self): 属性/赋值举例:
class Hero(object): """定义了一个英雄类,可以移动和攻击""" def __init__(self, name, skill, hp, atk, armor): """ __init__() 方法,用来做变量初始化 或 赋值 操作""" # 英雄名 self.name = name # 技能 self.skill = skill # 生命值: self.hp = hp # 攻击力 self.atk = atk # 护甲值 self.armor = armor def move(self): """实例方法""" print("%s 正在前往事发地点..." % self.name) def attack(self): """实例方法""" print("发出了一招强力的%s..." % self.skill) def info(self): print("英雄 %s 的生命值 :%d" % (self.name, self.hp)) print("英雄 %s 的攻击力 :%d" % (self.name, self.atk)) print("英雄 %s 的护甲值 :%d" % (self.name, self.armor)) # 实例化英雄对象时,参数会传递到对象的__init__()方法里 taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200) gailun = Hero("盖伦", "大宝剑", 4200, 260, 400) # print(gailun) # print(taidamier) # 不同对象的属性值的单独保存 print(id(taidamier.name)) print(id(gailun.name)) # 同一个类的不同对象,实例方法共享 print(id(taidamier.move())) print(id(gailun.move()))说明:
- 通过一个类,可以创建多个对象,就好比 通过一个模具创建多个实体一样
- init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)
1.当使用类名()创建对象时,会自动执行以下操作
- 为对象在内存中分配空间–创建对象
- 为对象的属性设置初始值–初始化方法(init())
- init()是对象的内置函数
- __init__方法时专门来定义一个类具有哪些属性的方法
- 使用类名()创建对象时,会自动调用初始化方法
- 在__init__方法内部使用self.属性=属性的初始化的方法就会定义属性
- 定义属性后在使用类创建对象都会拥有该属性
改造初始化方法
在开发中如果希望在创建对象的同时就设置对象的属性就要对__init__进行改造
1、把希望设置的属性值,定义成init方法的参数
2、在方法内部使用self.属性 = 形参接受外部传递的参数
3、在创建对象时,使用类名(属性1,属性2,。。。)调用
注意:
- 在类内部获取 属性 和 实例方法,通过self获取;
- 在类外部获取 属性 和 实例方法,通过对象名获取。
- 如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址;
- 但是实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法。
这个方法是一个魔法方法 (Magic Method) ,用来显示信息 该方法需要 return 一个数据,并且只有self一个参数,当在类的外部 print(对象) 则打印这个数据
如果在开发中,希望输出对象变量时,能够打印自定义内容,就可以使用__strl__这个内置方法
注意:str方法必须有一个返回值
结构:
class 类名称(object): def __init__(self,参数列表): 属性/赋值 def __str__(self): return 信息举例:
class Hero(object): """定义了一个英雄类,可以移动和攻击""" def __init__(self, name, skill, hp, atk, armor): """ __init__() 方法,用来做变量初始化 或 赋值 操作""" # 英雄名 self.name = name # 实例变量 # 技能 self.skill = skill # 生命值: self.hp = hp # 实例变量 # 攻击力 self.atk = atk # 护甲值 self.armor = armor def move(self): """实例方法""" print("%s 正在前往事发地点..." % self.name) def attack(self): """实例方法""" print("发出了一招强力的%s..." % self.skill) # def info(self): # print("英雄 %s 的生命值 :%d" % (self.name, self.hp)) # print("英雄 %s 的攻击力 :%d" % (self.name, self.atk)) # print("英雄 %s 的护甲值 :%d" % (self.name, self.armor)) def __str__(self): """ 这个方法是一个魔法方法 (Magic Method) ,用来显示信息 该方法需要 return 一个数据,并且只有self一个参数,当在类的外部 print(对象) 则打印这个数据 """ return "英雄 <%s> 数据: 生命值 %d, 攻击力 %d, 护甲值 %d" % (self.name, self.hp, self.atk, self.armor) taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200) gailun = Hero("盖伦", "大宝剑", 4200, 260, 400) # 如果没有__str__ 则默认打印 对象在内存的地址。 # 当类的实例化对象 拥有 __str__ 方法后,那么打印对象则打印 __str__ 的返回值。 print(taidamier) print(gailun) # 查看类的文档说明,也就是类的注释 print(Hero.__doc__)运行结果:
英雄 <泰达米尔> 数据: 生命值 2600, 攻击力 450, 护甲值 200 英雄 <盖伦> 数据: 生命值 4200, 攻击力 260, 护甲值 400 定义了一个英雄类,可以移动和攻击
6.2说明:- 在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
- 当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__str__(self)方法,那么就会打印从在这个方法中 return 的数据
- __str__方法通常返回一个字符串,作为这个对象的描述信息
- 当使用类名()创建对象时,为对象分配空间后,自动调用_init_()方法
- 当一个对象被从内存中销毁时会自动调用_init_()方法
结构:
class 类名称(object): def __init__(self,参数列表): 属性/赋值 def __str__(self): return 信息 def __del__(self,参数列表): 代码举例:
class Hero(object): # 初始化方法 # 创建完对象后会自动被调用 def __init__(self, name): print('__init__方法被调用') self.name = name # 当对象被删除时,会自动被调用 def __del__(self): print("__del__方法被调用") print("%s 被 GM 干掉了..." % self.name) # 创建对象 taidamier = Hero("泰达米尔") # 删除对象 print("%d 被删除1次" % id(taidamier)) del(taidamier) print("--" * 10) gailun = Hero("盖伦") gailun1 = gailun gailun2 = gailun print("%d 被删除1次" % id(gailun)) del(gailun) print("%d 被删除1次" % id(gailun1)) del(gailun1) print("%d 被删除1次" % id(gailun2)) del(gailun2)7.2总结- 当有变量保存了一个对象的引用时,此对象的引用计数就会加1;
- 当使用del() 删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)。
应用场景:
- __init__改造初始化方法,可以让创建对象更加灵活
- del()如果希望在对象被销毁前,在做一些事情,可以考虑一下__del__()方法
1、当一个对象被调用类名()创建,生命周期开始
2、一个对象的__del__方法一旦被调用,生命周期结束
3、对面向对象生命周期内,可以访问对象属性或者让对象调用方法
8.继承 8.1什么是继承?在生活中继承的含义一般是子女继承父辈的财产,而在程序中是指,类继承另外一个类的属性和方法。
- 在程序中,继承描述的是多个类之间的所属关系。
- 如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B里。
- 那么类A就是基类,也叫做父类;类B就是派生类,也叫做子类。
继承的概念:子类拥有父类的所有属性和方法
举例:
# 父类 class A(object): def __init__(self): self.num = 10 def print_num(self): print(self.num + 10) # 子类 class B(A): pass b = B() print(b.num) b.print_num()运行结果:
10 20
8.2单继承:子类只继承一个父类结构
class 类名称(父类名): 方法/属性举例:
# 老猫将自己的一身本领传给小猫 # 定一个父类 class Cat(object): def __init__(self): self.kongfu = "厉害的捉鱼本领" def make_fish(self): print("利用%s抓鱼" % self.kongfu) # MinCat,继承了Cat,Cat是父类。 class MinCat(Cat): pass xiaohua = MinCat() print(xiaohua.kongfu) xiaohua.make_fish()运行结果:
厉害的捉鱼本领 利用厉害的捉鱼本领抓鱼
说明:
- 虽然子类没有定义__init__方法初始化属性,也没有定义实例方法,但是父类有。所以只要创建子类的对象,就默认执行了那个继承过来的__init__方法
总结:
- 子类在继承的时候,在定义类时,小括号()中为父类的名字
- 父类的属性、方法,会被继承给子类
结构:
class 类名称(父类名1,父类名2): 方法/属性举例:
# 老猫将自己的一身本领传给小猫,同时狗狗也将自己看家的本事传给了小猫 # 定一个父类 class Cat(object): def __init__(self): self.kongfu = "厉害的捉鱼本领" def make_fish(self): print("利用%s抓鱼" % self.kongfu) # 定义第二个父类 class Dog(object): def __init__(self): self.kongfu = "厉害的看家本领" def kanmen(self): print("利用%s看家" % self.kongfu) # MinCat,继承了Cat、Dog,Cat、Dog是父类。 class MinCat(Cat,Dog): pass xiaohua = MinCat() print(xiaohua.kongfu) xiaohua.make_fish() xiaohua.kanmen()运行结果:
厉害的捉鱼本领 利用厉害的捉鱼本领抓鱼 利用厉害的捉鱼本领看家
说明:
- 多继承可以继承多个父类,也继承了所有父类的属性和方法
- 注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法
- 多个父类中,不重名的属性和方法,不会有任何影响。
子类的魔法属性__mro__决定了属性和方法的查找顺序
列子:
# 老猫将自己的一身本领传给小猫,同时狗狗也将自己看家的本事传给了小猫 # 定一个父类 class Cat(object): def __init__(self): self.kongfu = "厉害的捉鱼本领" def make_fish(self): print("利用%s抓鱼" % self.kongfu) # 定义第二个父类 class Dog(object): def __init__(self): self.kongfu = "厉害的看家本领" def kanmen(self): print("利用%s看家" % self.kongfu) # MinCat,继承了Cat、Dog,Cat、Dog是父类。 class MinCat(Cat, Dog): pass xiaohua = MinCat() print(MinCat.__mro__)运行结果:
(
, , , ) 注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)
- 5.1加减乘除(+- 我们都知道它们是什么含义了吧,就算你的数学是体育老师教的,你也会懂加减乘除吧。



