文章目录
- 一、变量和简单类型
-
- 1、单行注释/多行注释
- 2、变量
-
- 2.1、弱类型语言
- 2.2、使用print函数输出变量
- 2.3、变量的命名规则
- 2.4、Python关键字/内置函数
- 3、数值类型
-
- 3.1、整型(int)
- 3.2、浮点型(float)
- 3.3、复数
- 4、字符串
-
- 4.1、字符串/转义字符
- 4.2、拼接字符串
- 4.3、repr和字符串
- 4.4、使用input/raw_input获取用户输入
- 4.5、长字符串
- 4.6、原始字符串
- 4.7、bytes
- 5、深入使用字符串
-
- 5.1、转义字符
- 5.2、字符串格式化
- 5.3、序列相关方法
- 5.4、大小写相关方法
- 5.5、删除空白
- 5.6、查找/替换相关方法
- 5.7、分割/连接方法
- 6、运算符
-
- 6.1、赋值运算符
- 6.2、算数运算符
- 6.3、位运算符
- 6.4、扩展后的赋值运算符
- 6.5、索引运算符
- 6.6、比较运算符与bool类型
- 6.7、逻辑运算符
- 6.8、三目运算符
- 6.9、in运算符
- 6.10、运算符的结合性和优先级
- 二、列表、元组、字典
-
- 1、序列简介
-
- 1.1、Python的序列
- 1.2、创建列表和元组
- 2、列表和元组的通用方法
-
- 2.1、通过 索引使用元素
- 2.2、子序列
- 2.3、加法
- 2.4、乘法
- 2.5、in运算符
- 2.6、长度、最大值、最小值
- 2.7、序列封包、序列解包
- 3、使用列表
-
- 3.1、创建列表
- 3.2、增加列表元素
- 3.3、删除列表元素
- 3.4、修改列表元素
- 3.5、列表的其他常用方法
- 4、使用字典
-
- 4.1、字典入门
- 4.2、创建字典
- 4.3、字典的基本用法
- 4.4、字典的常用方法
- 4.5、使用字典格式化字符串
- 三、流程控制
-
- 1、顺序结构
- 2、if分支结构
-
- 2.1、不要忘记缩进
- 2.2、不要随意缩进
- 2.3、不要忘记冒号
- 2.4、if条件的类型
- 2.5、if分支的逻辑错误
- 2.6、if表达式
- 2.7、pass语句
- 3、断言
- 4、循环结构
-
- 4.1、while循环
- 4.2、使用while循环遍历列表和元组
- 4.3、for-in循环
- 4.4、使用for-in循环遍历列表和元组
- 4.5、使用for-in循环遍历字典
- 4.6、循环使用else
- 4.7、嵌套循环
- 4.8、for表达式
- 4.9、常用工具函数
- 5、控制循环结构
-
- 5.1、使用break结束循环
- 5.2、使用continue忽略本次循环的剩下语句
- 5.3、使用return方法
- 四、函数和lambda表达式
-
- 1、函数入门
-
- 1.1、理解函数
- 1.2、定义函数/调用函数
- 1.3、为函数提供文档
- 1.4、多个返回值
- 1.5、递归函数
- 2、函数的参数
-
- 2.1、关键字参数
- 2.2、参数默认值
- 2.3、参数收集(个数可变的参数)
- 2.4、逆向参数收集
- 2.5、函数的参数传递机制
- 2.6、变量作用域
- 3、局部函数
- 4、函数高级内容
-
- 4.1、使用函数变量
- 4.2、使用函数作为函数形参
- 4.3、使用函作为返回值
- 5、局部函数与lambda表达式
-
- 5.1、回顾局部函数
- 5.2、使用lambda表达式替代局部函数
- 五、类和对象
-
- 1、类和对象
-
- 1.1、定义类
- 1.2、对象的产生和使用
- 1.3、对象的动态性
- 1.4、实例方法和自动绑定self
- 2、方法
-
- 2.1、类也能调用实例方法
- 2.2、类方法与静态方法
- 2.3、@函数装饰器(还需进一步学习)
- 2.4、再论类命名空间
- 3、成员变量
-
- 3.1、类变量和实例变量
- 3.2、使用property函数定义属性
- 4、隐藏和封装(还需进一步学习)
- 5、类的继承
-
- 5.1、继承的语法
- 5.2、关于多继承
- 5.3、重写父类的方法
- 5.4、使用未绑定方法调用被重写的方法
一、变量和简单类型
1、单行注释/多行注释
注释对程序本身无影响,起解释说明作用(Python解释器会忽略注释内容)
单行注释:使用(#)号表示单行注释的开始
# print("这是单行注释!!!")
- 1
多行注释:使用三个单引号或者三个双引号将注释的内容括起来
"""
print("这是多行注释!!!")
"""
- 1
- 2
- 3
2、变量
Python是弱类型语言,有两个典型特征:
- 变量无需声明可直接赋值:对一个不存在的变量赋值就相当于定义了一个新变量;
- 变量的数据类型可动态改变:同一个变量可以一会儿被赋值为整数值,一会儿被赋值为字符串;
2.1、弱类型语言
2.2、使用print函数输出变量
print函数格式
def print(self, *args, sep=' ', end='\n', file=None):
- 1
value参数可以输出多个变量或值
user_name = "AlySam"
user_age = 18
print("用户名:", user_name, "年龄:", user_age) # 用户名: AlySam 年龄: 18
- 1
- 2
- 3
使用print()函数输出多个变量时,默认以空格隔开多个变量。如果需要改变分隔符,可设置sep
print("用户名:", user_name, "年龄:", user_age, sep='|') # 用户名:|AlySam|年龄:|18
- 1
在默认情况下print()函数输出之后会换行,end参数默认值为“\n”,可重新设置
print(user_name, '\t', end='')
print(user_age, '\t', end='') # AlySam 18
- 1
- 2
file参数指定print()函数的输出目标,file参数的默认值:sys.stdout。该默认值代表了系统标准输出(屏幕)。
f = open("ceshi.txt", "w", encoding="utf-8")
print("沧海月明珠有泪", file=f)
print("蓝田日暖玉生烟", file=f) # ceshi.txt文件中处输出对应的内容
f.close()
- 1
- 2
- 3
- 4
2.3、变量的命名规则
- 标识符可以由字母、数字、下划线(_)组成,其中不能以数字开头;
- 标识符不能是Python关键字,但可以包含关键字;
- 标识符不能包含空格;
2.4、Python关键字/内置函数
关键字
import keyword
print(keyword.kwlist)
- 1
- 2
‘False’, ‘None’, ‘True’, ‘peg_parser’, ‘and’, ‘as’, ‘assert’, ‘async’, ‘await’, ‘break’, ‘class’, ‘continue’, ‘def’, ‘del’, ‘elif’, ‘else’, ‘except’, ‘finally’, ‘for’, ‘from’, ‘global’, ‘if’, ‘import’, ‘in’, ‘is’, ‘lambda’, ‘nonlocal’, ‘not’, ‘or’, ‘pass’, ‘raise’, ‘return’, ‘try’, ‘while’, ‘with’, ‘yield’
内置函数
abs() | all() | any() | basestring() | bin() | bool() | bytearray() | callable() |
---|---|---|---|---|---|---|---|
chr() | classmethod() | cmp() | compile() | complex() | delattr() | dict() | dir() |
divmod() | enumerate() | eval() | execfile() | file() | filter() | float() | format() |
frozenset() | getattr() | globals() | hasattr() | hash() | help() | hex() | id() |
input() | int() | isinstance() | issubclass() | iter() | len() | list() | locals() |
long() | map() | max() | memoryview() | min() | next() | object() | oct() |
open() | ord() | pow() | print() | propetry() | range() | raw_input() | reduce() |
reload() | repr() | reversed() | round() | zip() | set() | setattr() | slice() |
sorted() | staticmethod() | str() | sum() | super() | tuple() | type() | unichr() |
unicode() | vars() | xrange() | Zip() | import() | apply() | buffer() | coerce() |
intern |
3、数值类型
3.1、整型(int)
Python整型支持None值(空值)
a = None
print(a)
print(type(a))
- 1
- 2
- 3
- 十进制形式:
- 二进制形式:以0b/0B开头的整数
- 八进制形式:以0o/0O开头的整数
- 十六进制形式:以0x/0X开头的整数
Python允许数值(包括浮点型)增加下划线作为分隔符
one_million = 1_000_000
print(one_million) # 1000000
- 1
- 2
3.2、浮点型(float)
- 十进制形式:5.12
- 科学计数形式:5.12e2(5.1210²)/5.12E2(5.1210²)
只有浮点型数值才可以使用科学计数形式表示
Python不允许除以0。不管是整型数值、浮点型数值。
3.3、复数
导入模块:cmath(c—–complex)
import cmath
ac1 = 3 + 0.2j
ac2 = 4 - 0.1j
print(ac1 + ac2)
ac3 = cmath.sqrt(-1)
print(ac3)
- 1
- 2
- 3
- 4
- 5
- 6
4、字符串
单引号/双引号括起来
4.1、字符串/转义字符
字符串可以使用单引号括起来,也可以使用双引号括起来。如果字符串本身包含了单/双引号,需要进行特殊处理
- 使用不同的引号将字符串括起来
- 对引号进行转义
# 字符串 I'm a doctor.
# str1 = 'I'm a doctor.'
str2 = "I'm a doctor."
print(str2)
- 1
- 2
- 3
- 4
本身仅包含单引号,外部可使用双引号;同理仅包含双引号,外部可使用单引号
str3 = '"we are scraed, Let\'s hide in the shade", says the birds'
print(str3) # "we are scraed, Let's hide in the shade", says the birds
- 1
- 2
4.2、拼接字符串
直接将两个字符串紧挨着写在一起,Python会自动拼接
str4 = "Hello " "Python"
print(str4) # Hello Python
- 1
- 2
该方法只是书写字符串的一种特殊方法,并不能真正的用于字符串的拼接。Python使用(+)作为字符串的拼接运算符
str5 = "Hello "
str6 = "Python"
new_str = str5 + str6
print(new_str) # Hello Python
- 1
- 2
- 3
- 4
4.3、repr和字符串
部分情况下需要将字符串与数值进行拼接,而Python不允许直接拼接字符串和数值,需将数值转化为字符串进行拼接
将数值转化为字符串可以使用函数:str()/prer()
str1 = "这本书的价格是:"
price1 = 69.8
new_str1 = str1 + repr(price1)
new_str2 = str1 + str(price1)
print(new_str1)
print(new_str2) # 这本书的价格是:69.8
- 1
- 2
- 3
- 4
- 5
- 6
repr()另外功能,以Python表达式的形式来表示值(带引号的字符串)
str7 = 'AlySam'
print(repr(str7)) # 'AlySam'
- 1
- 2
4.4、使用input/raw_input获取用户输入
input()函数用于向用户生成一条提示,然后获取用户输入的内容。(input()函数总是返回一个字符串)
msg = input("请输入值:\n")
print(type(msg))
# 输出结果:
# 请输入值:
# 12
# <class 'str'>
- 1
- 2
- 3
- 4
- 5
- 6
Python2.x中的raw_input()函数就相当于input()函数
4.5、长字符串
长字符串可以赋值给变量
str8 = """ "Let's go fishing", said Mary."""
print(str8) # "Let's go fishing", said Mary.
- 1
- 2
使用转义字符对换行符进行转义,转义之后的换行符不会“中断”字符串
str9 = 'The quick brown fox ' \
'jumps over the lazy dog.'
print(str9) # The quick brown fox jumps over the lazy dog.
- 1
- 2
- 3
4.6、原始字符串
原始字符串以“r”开头,原始字符串中不会把反斜线当成特殊字符
str10 = r"E:\Users\PycharmProjects\Auto_Testing_01\Common\basepage.py"
print(str10) # E:\Users\PycharmProjects\Auto_Testing_01\Common\basepage.py
- 1
- 2
如果原始字符串中包含引号,需要对引号进行转义,但此时用于转义的反斜线会变成字符串的一部分
str2 = r'"Let \'s go", said Mary.'
print(str2) # "Let \'s go", said Mary.
- 1
- 2
字符串尾部需要反斜线输出
str2 = r"Let us go!" "\\"
print(str2) # Let us go!\
- 1
- 2
4.7、bytes
bytes类型,代表字节:由多个字节组成,已字节为单位进行操作
将一个字符串转换成bytes对象:
- 如果字符串内容都是ASCII字符,则可以通过直接在字符串前加b来构建;
- 调用bytes函数
- 调用字符串本身的uncode方法将字符串按指定字符集转成字符串,如果不指定,则默认使用UTF-8字符集;
# 创建一个空的bytes
b1 = bytes()
# 创建一个空的bytes值
b2 = b''
b3 = b'hello'
print(b3)
print(b3[0])
print(b3[2:4])
b4 = bytes("我爱编程", encoding='utf-8')
print(b4)
b5 = "学习编程".encode('utf-8')
print(b5)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
# 输出结果:
# b'hello'
# 104
# b'll'
# b'\xe6\x88\x91\xe7\x88\xb1\xe7\xbc\x96\xe7\xa8\x8b'
# b'\xe5\xad\xa6\xe4\xb9\xa0\xe7\xbc\x96\xe7\xa8\x8b'
- 1
- 2
- 3
- 4
- 5
- 6
5、深入使用字符串
5.1、转义字符
转义字符 | 说明 |
---|---|
\b | 退格符 |
\n | 换行符 |
\r | 回车符 |
\t | 制表符 |
“ | 双引号 |
’ | 单引号 |
\ | 反斜线 |
str1 = "Hello\nPython"
print(str1)
str3 = "商品名\t\t\t\t单价\t\t\t数量"
str4 = "疯狂Python讲义\t\t69.8\t\t2"
print(str3)
print(str4)
- 1
- 2
- 3
- 4
- 5
- 6
输出结果:
Hello
Python
商品名 单价 数量
疯狂Python讲义 69.8 2
- 1
- 2
- 3
- 4
- 5
5.2、字符串格式化
Python提供“%”对各种类型的数据进行格式化输出
price = 69.8
print("The book's price is %s." % price) # The book's price is 69.8.
- 1
- 2
%s表示占位符 % 作为固定使用的分隔符
name = "Python讲义"
price = 69.8
print("%s的价格是:%s元" % (name, price)) # Python讲义的价格是:69.8元
- 1
- 2
- 3
转换说明符
转换说明符 | 说明 |
---|---|
d/i | 带符号的十进制整数 |
o | 带符号的八进制整数 |
x/X | 带符号的十六进制整数 |
e/E | 科学计数法表示的浮点数 |
f/F | 十进制形式的浮点数 |
g/G | 智能选择使用f/e(F/E)格式 |
C | 单字符(只接受整数或单字符字符串) |
r | 使用repr()将变量或表达式转换为字符串 |
s | 使用str()将变量或表达式转换为字符串 |
指定字符串的最小宽度
num = -28
print("Num is: %6i" % num) # Num is: -28
- 1
- 2
- -:指定左对齐;
- +:表示数值总是要呆着符号(正数:+;负数:-);
- 0:表示不补充空格,补充0;
num = 28
print("Num is: %06i" % num) # Num is: 000028
print("Num is: %+06i" % num) # Num is: +00028
print("Num is: %-6i" % num) # Num is: 28
- 1
- 2
- 3
- 4
对于转换浮点数,允许指定小数点后的数字位数;如果转换的是字符串,允许指定转换后的字符串的最大字符数,这个标志被称之为精度值,精度值被放在最小宽度之后,中间用点(.)隔开。
my_value = 3.001415926535
# 宽度为8,小数点保留3位
print("my_value is: %8.3f" % my_value) # my_value is: 3.001
# 宽度为8,小数点保留3位,左边补0
print("my_value is: %08.3f" % my_value) # my_value is: 0003.001
# 宽度为8,小数点保留3位,左边补0,带符号
print("my_value is: %+08.3f" % my_value) # my_value is: +003.001
- 1
- 2
- 3
- 4
- 5
- 6
- 7
5.3、序列相关方法
Python字符串直接在方括号([])中使用索引即可获取对应的字符,索引从0开始;从最后开始计算索引,索引值从-1开始。
允许省略起始索引/结束索引
str1 = "crazy"
print(str1[1]) # r
print(str1[-1]) # y
print(str1[1:3]) # ra
print(str1[:3]) # cra
print(str1[2:]) # azy
- 1
- 2
- 3
- 4
- 5
- 6
支持用in运算符判断是否包含某个子字符串
str1 = "crazy"
print('ray' in str1) # False
print('ra' in str1) # True
- 1
- 2
- 3
获取字符串的长度:内置函数len
str1 = "crazy"
print(len(str1)) # 5
- 1
- 2
获取字符串中最小字符/最大字符
str1 = "crazy"
print(max(str1)) # z
print(min(str1)) # a
- 1
- 2
- 3
5.4、大小写相关方法
两个帮助函数:
- dir():列出指定类或模块包含的全部内容
- help():查看某个函数或方法的帮助文档
相关函数介绍:
- title():将每个单词的首字母改为大写;
- lower():将整个字符串改为小写;
- upper():将整个字符串改为大写
Str = "our domain IS crazyit.org"
print(Str.title())
print(Str.lower())
print(Str.upper())
# 输出结果:
# Our Domain Is Crazyit.Org
# our domain is crazyit.org
# OUR DOMAIN IS CRAZYIT.ORG
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5.5、删除空白
方法说明:
- strip():删除字符串前后的空白
- lstrip():删除字符串前面(左边)的空白
- rstrip():删除字符串后面(右边)的空白
str2 = " this is a joker!!! "
print(str2.strip())
print(str2.lstrip())
print(str2.rstrip())
# 输出结果:
# this is a joker!!!
# this is a joker!!!
# this is a joker!!!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5.6、查找/替换相关方法
方法说明:
- startwith():判断字符串是否已指定字符开头
- endwith():判断字符串是否已指定字符结尾
- find():查找子串在字符串中出现的位置,如没有找到指定子串,返回-1
- index():查找子串在字符串中出现的位置,如没有找到指定子串,引发ValueError错误
- replace():使用指定的子串代替字符串中的目标字串
- translate():使用指定的翻译映射表对字符串执行替换
str2 = "this is a joker!!!"
print(str2.startswith('this')) # True
print(str2.endswith('!')) # True
print(str2.find('his')) # 1
print(str2.find('ahis')) # -1
# 引发错误
# print(str2.index('ahis'))
print(str2.replace('is', 'our')) # thour our a joker!!!
print(str2.replace('is', 'our', 1)) # thour is a joker!!!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
5.7、分割/连接方法
方法说明:
- split():将字符串按指定分割符分割成多个短语
- join():将多个短语连接成字符串
str2 = "this is a joker!!!"
# 使用空白对字符进行分割
print(str2.split('.')) # ['this is a joker!!!']
print(str2.split()) # ['this', 'is', 'a', 'joker!!!']
new_list = str2.split()
print('/'.join(new_list)) # this/is/a/joker!!!
- 1
- 2
- 3
- 4
- 5
- 6
6、运算符
种类:
- 赋值运算符
- 算数运算符
- 位运算符
- 索引运算符
- 比较运算符
- 逻辑运算符
6.1、赋值运算符
赋值运算符用于为变量或常量指定值,Python中使用“=”作为赋值运算符
# 将字符串Python赋值给str3
str3 = "Python"
# 给变量pi赋值为:3.14
pi = 3.14
# 将一个变量的值赋值给另一个变量
str4 = str3
- 1
- 2
- 3
- 4
- 5
- 6
6.2、算数运算符
七个基本的算数运算符
+:加法运算符
num1 = 1.2
num2 = 2.1
print(num1 + num2) # 3.3
- 1
- 2
- 3
-:减法运算符
num1 = 3.2
num2 = 2.1
print(num1 - num2) # 1.1
- 1
- 2
- 3
求负运算
x = -5
new_x = -x
print(new_x) # 5
- 1
- 2
- 3
*:乘法运算符
num1 = 3.2
num2 = 2
print(num1 * num2) # 6.4
- 1
- 2
- 3
str = "crazy "
print(str * 5) # crazy crazy crazy crazy crazy
- 1
- 2
/或者//:除法运算符
“/”:表示普通除法,结果正常显示;
“//”:表示整除,整除之后的结果只有整数部分,小数部分将会被舍弃;
print(19/5) # 3.8
print(19//5) # 3
- 1
- 2
%:求余运算符
求余操作不仅支持整数、也支持浮点数
print(19 % 5) # 4
print(5.2 % 3.1) # 2.1
- 1
- 2
**:乘方运算符
print(5 ** 2) # 25
print(4 ** 0.5) # 2.0
print(27 ** (1 / 3)) # 3.0
- 1
- 2
- 3
6.3、位运算符
位运算符通常在图形、图像处理、创建设备驱动等底层开发中应用。使用位运算符可以直接操作数值的原始bit位。
位运算符:6个
- &:按位与
- |:按位或
- ^:按位异或
- ~:按位取反
- “<<”:左位移运算符
- “>>”:右位移运算符
6.4、扩展后的赋值运算符
- +=
- -=
- *=
- /=
- //=
- %=
- **=
- &=
- |=
- ^=
- <<= >>=
6.5、索引运算符
[]
str1 = "asjhdakjlkajskl"
print(str1[1:5:2]) # sh
- 1
- 2
6.6、比较运算符与bool类型
True False
bool类型就是用于代表某个事情的真或假,正确的用True代表,错误用False代表。
比较运算符用于判断两个值:
“>”:
“>=”:
“<”:
“<=”:
“==”:
“!=”:
“is”:
“is not”:
print(5 > 4)
print(5 >= 4)
print(5 == 5.0)
print(1 == True)
- 1
- 2
- 3
- 4
== 与 is有实质区别, ==只是表示两个变量的值,但is要求两个变量引用同一个对象
import time
a = time.gmtime()
b = time.gmtime()
print(a == b) # True
print(a is b) # False
print(id(a))
print(id(b))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
6.7、逻辑运算符
逻辑运算符用于操作bool类型的变量、常量、表达式,逻辑运算符的返回值也是bool值。
- and:与 前后两个操作数都必须是True才返回True;
- or:或 两个操作数中有一个操作数为True时返回True;
- not:非 只需要一个操作数,操作数为True,返回False,反之同理;
print(not False) # True
print(5 > 3 and 20 > 21) # False
print(5 > 3 or 20 > 21) # True
- 1
- 2
- 3
6.8、三目运算符
格式:
True_statement if expression else False_statement
- 1
运算规则:先对逻辑表达式expression求值,返回True,执行并返回True_statement的值,反之执行并返回False_statement的值
a = 20
b = 3
st = "a > b" if a > b else "a不大于b"
print(st) # a > b
- 1
- 2
- 3
- 4
6.9、in运算符
用于判断某个成员是否在序列中
str2 = 'asdjalskjdla'
print('as' in str2) # True
print('as' not in str2) # False
- 1
- 2
- 3
6.10、运算符的结合性和优先级
二、列表、元组、字典
1、序列简介
序列:指的是一种包含多项数据的数据结构,序列包含的多个数据项(成员)按顺序排列,可通过索引来访问成员。
1.1、Python的序列
Python的常见序列类型包含字符串、列表和元组等。(元组是不可变的、列表可变)
1.2、创建列表和元组
创建列表[ ] 创建元组( ) 元素之间以英文隔开
创建列表的格式:
[ele1, ele2, ele3, …]
创建元组的格式:
(ele1, ele2, ele3, …)
2、列表和元组的通用方法
2.1、通过 索引使用元素
从左到右索引以0开始,从右到左索引以-1开始
列表的元素相当于一个变量,可以使用它的值,也可以重新对元素赋值;元组的元素相当于一个常量,仅可以使用它的值。
a_tuple = ('crazy', 20, 5.6, "Python", -17)
print(a_tuple[0]) # crazy
- 1
- 2
2.2、子序列
列表和元组同样可使用索引来获取其中一段,即切片(slice)
[start : end : step] step:表示步长
a_tuple = ('crazy', 20, 5.6, "Python", -17)
print(a_tuple[1:3]) # (20, 5.6)
print(a_tuple[1:6:3]) # (20, -17)
- 1
- 2
- 3
2.3、加法
列表和元组都支持加法运算,加法的和就是两个列表或元组所包含的元素的总和
列表仅能和列表相加,元组仅能和元组相加
a_tuple = ('crazy', 20, 5.6, "Python", -17)
b_tuple = ('Hello', 'pi')
print(a_tuple + b_tuple) # ('crazy', 20, 5.6, 'Python', -17, 'Hello', 'pi')
a_list = ['crazy', 20, 5.6, "Python", -17]
b_list = ['Hello', 'pi']
print(a_list + b_list) # ['crazy', 20, 5.6, 'Python', -17, 'Hello', 'pi']
- 1
- 2
- 3
- 4
- 5
- 6
2.4、乘法
列表和元组可以进行乘法运算,意义:把其包含的元素重复N次(N为被乘的倍数)
b_tuple = ('Hello', 'pi')
print(b_tuple * 2 ) # ('Hello', 'pi', 'Hello', 'pi')
b_list = ['Hello', 'pi']
print(b_list * 2 ) # ['Hello', 'pi', 'Hello', 'pi']
- 1
- 2
- 3
- 4
2.5、in运算符
用于判断列表或元组是否包含某个元素
print(20 in b_tuple) # FALSE
print(20 in b_list) # FALSE
- 1
- 2
2.6、长度、最大值、最小值
a_tuple = (20, 5.6, -17, 102)
print(max(a_tuple)) # 102
print(min(a_tuple)) # -17
print(len(a_tuple)) # 4
- 1
- 2
- 3
- 4
元素若为字符串,则依次比较ASCII吗值
2.7、序列封包、序列解包
序列封包(Sequence Packing)和序列解包(Sequence Unpacking)的功能
两种赋值形式:
- 程序把多个值赋值给一个变量时,Python会自动将多个值封装成元组;(序列封包)
- 程序允许将(元组/列表)直接赋值给多个变量,此时序列的各元素会依次赋值给每个变量(要求序列的元素个数和变量个数相等);(序列解包)
var = 10, 20, 30
print(var) # a, b, c, d, e
print(type(var))# a, b, c, d, e
a_tuple = tuple(range(1,10,2))
a, b, c, d, e = a_tuple
print(a, b, c, d, e) # a, b, c, d, e
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在序列解包时也可以只解出部分变量,剩下的依然使用列表变量保存。为了使用这种解包方式,Python允许在左边被赋值的变量之前添加“*”
first, second, *rest = range(10)
print(first) # 0
print(second) # 1
print(rest) # [2, 3, 4, 5, 6, 7, 8, 9]
*rest, last = range(4)
print(rest) # [0, 1, 2]
print(last) # 3
first, *middle, last = range(5)
print(first) # 0
print(middle) # [1, 2, 3]
print(last) # 4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3、使用列表
3.1、创建列表
除了基本格式外,可用list( )内置函数来创建,将元组/区间(range)等对象转化为列表
b_tuple = ('Hello', 'pi')
print(list(b_tuple)) # ['Hello', 'pi']
- 1
- 2
3.2、增加列表元素
append( )方法:把传入的参数追加到列表的最后面。既可以接收单个值,也可以接收元组、列表等,但是该方法只是把元组、列表当成单个元素处理。
a_list = ['Hello', 'pi']
a_tuple = ('Hello', 'pi')
# a_list.append('123')
a_list.append(a_tuple)
print(a_list) # ['Hello', 'pi', ('Hello', 'pi')]
- 1
- 2
- 3
- 4
- 5
如果不希望追加的列表未一个整体,可以使用extend( )
a_list = ['Hello', 'pi']
a_tuple = ('Hello', 'pi')
a_list.extend(a_tuple)
print(a_list) # ['Hello', 'pi', 'Hello', 'pi']
- 1
- 2
- 3
- 4
在列表某个位置添加元素,insert( )
a_list = ['Hello', 'pi']
a_tuple = ('Hello', 'pi')
a_list.extend(a_tuple)
print(a_list) # ['Hello', 'pi', 'Hello', 'pi']
a_list.insert(2, 'insert_test')
print(a_list) # ['Hello', 'pi', 'insert_test', 'Hello', 'pi']
- 1
- 2
- 3
- 4
- 5
- 6
3.3、删除列表元素
列表删除元素使用del语句。使用del语句可以删除列表中的单个元素,也可以删除列表中的一段
a_list = ['Hello', 'pi', 'insert_test', 'Hello', 'pi']
del a_list[1]
print(a_list) # ['Hello', 'insert_test', 'Hello', 'pi']
del a_list[2:3]
print(a_list) # ['Hello', 'pi', 'Hello', 'pi']
- 1
- 2
- 3
- 4
- 5
del不仅可以删除元素,还可以删除普通变量
name = 'AlySam'
print(name) # AlySam
del name
print(name) # NameError: name 'name' is not defined
- 1
- 2
- 3
- 4
remove( ) :直接删除找到的第一个元素,若没元素,则报错ValueError
a_list = ['Hello', 'pi', 'insert_test', 'Hello', 'pi']
a_list.remove('Hello')
print(a_list) # ['pi', 'insert_test', 'Hello', 'pi']
- 1
- 2
- 3
clear( ) :清空列表的所有元素
a_list = ['Hello', 'pi', 'insert_test', 'Hello', 'pi']
a_list.clear()
print(a_list) # []
- 1
- 2
- 3
3.4、修改列表元素
通过索引对列表元素赋值,既可正数索引,也可负数索引
b_list = ['Hello', 'pi', 'insert_test', 'Hello', 'pi']
b_list[3] = 'update_list'
print(b_list)
- 1
- 2
- 3
b_list = list(range(1,5))
b_list[1:3] = ['a', 'b']
print(b_list) # [1, 'a', 'b', 4]
- 1
- 2
- 3
3.5、列表的其他常用方法
dir(list):查看列表的所有方法
print(dir(list))
- 1
[‘add’, ‘class’, ‘class_getitem’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘iadd’, ‘imul’, ‘init’, ‘init_subclass’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘reversed’, ‘rmul’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘append’, ‘clear’, ‘copy’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’, ‘remove’, ‘reverse’, ‘sort’]
常用方法说明:
- count():统计列表中某个元素出现的次数
- index():判断列表中某个元素出现的位置
- pop():将列表当成“栈”使用,实现元素出栈功能
- reverse():将列表中的元素反向存放
- sort():对列表元素进行排序
s_list = [2, 30, [5, 30], 30, 223]
print(s_list.count(30)) # 2 [5, 30]为一个元素整体
- 1
- 2
s_list = [2, 30, [5, 30], 30, 223]
print(s_list.index(30, 2)) # 3 2表示从索引2开始,查找30出现的位置
- 1
- 2
stack = []
stack.append('num1')
stack.append('num2')
stack.append('num3')
print(stack) # ['num1', 'num2', 'num3']
# 第一次出栈,最后入栈的元素先出栈
print(stack.pop()) # num3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
list_1 = ['num1', 'num2', 'num3']
list_1.reverse()
print(list_1) # ['num3', 'num2', 'num1']
- 1
- 2
- 3
list_1 = [12, 0.2, 25, 128, -25]
list_1.sort()
# 默认从小到大排序
print(list_1) # [-25, 0.2, 12, 25, 128]
list_2 = ['Python', 'Swift', 'Ruby', 'Go', 'Kotlin']
# 默认按照字符串包含的字符的编码来比较大小
list_2.sort()
print(list_2) # ['Go', 'Kotlin', 'Python', 'Ruby', 'Swift']
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
sort()两个参数 key reserve
key 参数用于为每个元素都生成一个比较大小的“键”,reserve参数用来执行是否需要反转排序(默认为从小到大排序),若将该参数设置为True,将会改为从大到小排序
list_2.sort(key=len)
print(list_2) # ['Go', 'Ruby', 'Swift', 'Kotlin', 'Python']
list_2.sort(reverse=True)
print(list_2) # ['Swift', 'Ruby', 'Python', 'Kotlin', 'Go']
- 1
- 2
- 3
- 4
4、使用字典
4.1、字典入门
key—-value:通过key来访问value值(key不允许重复)
4.2、创建字典
可以使用花括号创建、也可以使用dict( )函数创建
元组可以作为dict的key,列表不行(key必须是不可变类型)
# 空字典
dict_1 = {}
print(dict_1 ) # {}
scores = {'语文': 89, '数学': 90, '英语': 95}
print(scores) # {'语文': 89, '数学': 90, '英语': 95}
dict_2 = {(20, 30): 'good', 40: 'bad'}
print(dict_2 ) # {(20, 30): 'good', 40: 'bad'}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4.3、字典的基本用法
- 通过key访问value
- 通过key添加key-value对
- 通过key删除key-value对
- 通过key修改key-value对
- 通过key判断指定key-value对是否存在
scores = {'语文': 89, '数学': 90, '英语': 95}
print(scores['语文']) # 89
scores['历史'] = 87
print(scores) # {'语文': 89, '数学': 90, '英语': 95, '历史': 87}
del scores['语文']
print(scores) # {'数学': 90, '英语': 95, '历史': 87}
# 对已存在的key赋值后,新值会替换原来的旧值
scores['语文'] = 99
print(scores) # {'语文': 99, '数学': 90, '英语': 95}
print('AUDO' in scores) # False
print('语文' in scores) # True
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4.4、字典的常用方法
字典的常用方法:
print(dir(dict))
- 1
[‘class’, ‘class_getitem’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘ior’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘ne’, ‘new’, ‘or’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘reversed’, ‘ror’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘clear’, ‘copy’, ‘fromkeys’, ‘get’, ‘items’, ‘keys’, ‘pop’, ‘popitem’, ‘setdefault’, ‘update’, ‘values’]
clear():清空字典中的所有键值对
scores = {'语文': 89, '数学': 90, '英语': 95}
scores.clear()
print(scores) # {}
- 1
- 2
- 3
get():根据key来获取value,如果获取的value值不存在时,返回None
scores = {'语文': 89, '数学': 90, '英语': 95}
print(scores.get('历史')) # None
- 1
- 2
update():使用一个字典包含的key-value对来更新已有的字典:有则覆盖,没有则添加
scores = {'语文': 89, '数学': 90, '英语': 95}
scores.update({'语文': 99, '历史': 75})
print(scores) # {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
- 1
- 2
- 3
items():获取字典中的所有键值对,返回dict_items
keys():获取字典中的所有key值,返回dict_keys
values():获取字典中的所有value值,返回dict_values
dict_1 = {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
items = dict_1.items()
print(items) # dict_items([('语文', 99), ('数学', 90), ('英语', 95), ('历史', 75)])
print(type(items)) # <class 'dict_items'>
print(list(items))
kys = dict_1.keys()
print(kys) # dict_keys(['语文', '数学', '英语', '历史'])
print(list(kys)) # ['语文', '数学', '英语', '历史']
vls = dict_1.values()
print(vls) # dict_values([99, 90, 95, 75])
print(list(vls)) # [99, 90, 95, 75]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
pop():用来获取指定key对应的value,并删除这个key-value对
dict_1 = {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
print(dict_1.pop('语文')) # 99
print(dict_1) # {'数学': 90, '英语': 95, '历史': 75}
- 1
- 2
- 3
popitem():可认为弹出字典中的最后一个键值对,弹出的是一个元组
dict_1 = {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
print(dict_1.popitem()) # ('历史', 75)
print(dict_1) # {'语文': 99, '数学': 90, '英语': 95}
- 1
- 2
- 3
setdefault():根据key值来获取对应的value值
dict_1 = {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
# 设置默认值,若key值不存在,新增key-value键值对
print(dict_1.setdefault('政治', 80)) # 80
print(dict_1) # {'语文': 99, '数学': 90, '英语': 95, 'zhengzhi': 80}
# 设置默认值,若key存在,不会修改dict内容
print(dict_1.setdefault('语文', 70)) # 99
print(dict_1) # {'语文': 99, '数学': 90, '英语': 95, '政治': 80}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
fromkeys():使用给定的多个key创建字典,key对应的value默认都是None
dict_2 = dict.fromkeys(['a', 'b'])
print(dict_2) # {'a': None, 'b': None}
dict_3 = dict.fromkeys(('a', 'b'))
print(dict_3) # {'a': None, 'b': None}
dict_4 = dict.fromkeys(('a', 'b'), 'good')
print(dict_4) # {'a': 'good', 'b': 'good'}
- 1
- 2
- 3
- 4
- 5
- 6
4.5、使用字典格式化字符串
# 创建字典
book = {'name': '疯狂python讲义', 'price': 69.9, 'publish': '电子社'}
# 在字符串模板中使用key
temp = '书名是:%(name)s,价格是:%(price).2f元, 出报社是:%(publish)s'
print(temp % book) # 书名是:疯狂python讲义,价格是:69.90元, 出报社是:电子社
- 1
- 2
- 3
- 4
- 5
三、流程控制
1、顺序结构
顺序结构是程序从上到下一行行地执行
2、if分支结构
if分支使用布尔表达式或布尔值作为分支条件进行分支控制
if语句的三种形式
# 第一种形式
if expression:
statements...
- 1
- 2
- 3
# 第二种形式
if expression:
statements...
else:
statements...
- 1
- 2
- 3
- 4
- 5
# 第三种形式
if expression:
statements...
elif expression:
statements...
...//零条/多条elif语句
else:
statements...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
user_age = int(input('请输入你的年龄:\n'))
if user_age >= 18:
print('成年!')
else:
print('未成年!')
- 1
- 2
- 3
- 4
- 5
2.1、不要忘记缩进
代码块一定要缩进(if条件后的条件执行体一定要缩进)
2.2、不要随意缩进
缩进必须保持一致(同一个代码块中的所有语句都必须保持相同的缩进)
2.3、不要忘记冒号
if user_age >= 18:
- 1
2.4、if条件的类型
Python执行if语句时,会判断if条件是True还是False,if条件可以是任意类型,当下面的值作为表达式时,会被解释器作为False处理
除了False本身,各种代表“空”的None、空字符串、空元祖、空列表、空字典都会被当成False处理
False、None、0、""、()、[]、{}
- 1
2.5、if分支的逻辑错误
可以先处理包含范围较小的情况
2.6、if表达式
2.7、pass语句
空语句:pass语句
3、断言
assert断言:
if 条件为False:
程序引发AssertionError错误
- 1
- 2
user_age = int(input('请输入你的年龄:\n'))
assert 18 <= user_age
print('成年')
# 输出结果:
# 1
# Traceback (most recent call last):
# File "E:\Users\PycharmProjects\Auto_Testing_01\ceshi.py", line 313, in <module>
# assert 18 <= user_age
# AssertionError
# 输出结果:
# 24
# 成年
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
4、循环结构
循环语句可以在满足循环条件的情况下,反复执行某一段代码,被重复执行的代码为循环体。反复执行循环体、知道判断条件为假时,跳出执行。
循环语句可能包含如下4部分内容:
- 初始化语句:
- 循环条件:
- 循环体:
- 迭代语句:
4.1、while循环
while循环的语法格式:
[init_statements]
while test_expression:
body_statements
[iteration_statements]
- 1
- 2
- 3
- 4
while循环在每次执行循环体之前,都要先对test_expression循环条件求值,值为真,则运行循环体部分。
i = 0
while i <= 3:
print("循环次数:", i)
i += 1
print('循环结束!')
# 输出结果:
# 循环次数: 0
# 循环次数: 1
# 循环次数: 2
# 循环次数: 3
# 循环结束!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4.2、使用while循环遍历列表和元组
通过列表、元组索引实现遍历
list_1 = ['Python', 'Java', 'C', 'C#']
i = 0
while i < len(list_1):
print(list_1[i])
i += 1
- 1
- 2
- 3
- 4
- 5
list_1 = [12, 45, 34, 13, 100, 24, 56, 74, 109]
# 存储整除3
list_a = []
# 存储除3余1
list_b = []
# 存储除3余2
list_c = []
while len(list_1) > 0:
# 弹出最后一个元素进行判断
ele = list_1.pop()
if ele % 3 == 0:
list_a.append(ele)
elif ele % 3 == 1:
list_b.append(ele)
else:
list_c.append(ele)
print(list_a)
print(list_b)
print(list_c)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4.3、for-in循环
for-in循环专门用于遍历范围、列表、元素、字典等可迭代对象包含的元素。for-in循环的语法格式:
for 变量 in 字符串/范围/集合等:
statements
- 1
- 2
- for-in循环中的变量的值受for-in循环控制,该变量将会在每次循环开始时自动被赋值;
- for-in循环可用于遍历任何迭代对象
num_1 = int(input("请输入想要阶乘的数据:\n"))
multi = 1
for i in range(1, num_1):
multi *= i
print(multi)
- 1
- 2
- 3
- 4
- 5
4.4、使用for-in循环遍历列表和元组
list_1 = ['Python', 'Java', 'C', 'C#']
for i in list_1:
print(i)
- 1
- 2
- 3
isinstance()函数用来判断变量是否为指定类型
list_1 = ['Python', 'Java', 'C', 'C#']
for i in range(0, len(list_1)):
print("第%d个元素是%s:"% (i, list_1[i]))
# 输出结果:
# 第0个元素是Python:
# 第1个元素是Java:
# 第2个元素是C:
# 第3个元素是C#:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
4.5、使用for-in循环遍历字典
- items():返回字典中所有key-value对的列表
- keys():返回字典中所有key的列表
- values():返回字典所有value的列表
dict_1 = {'语文': 99, '数学': 90, '英语': 95, '历史': 75}
for key, value in dict_1.items():
print("key", key)
print("value", value)
for key in dict_1.keys():
print("key", key)
for value in dict_1.values():
print("value", value)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
举例:统计列表中各元素出现的次数:已列表元素为key,出现的次数为value
list_test = [12, 45, 3.4, 12, 'fkit', 45, 3.4, 45, 3.4, 'fkit']
# 定义一个空字典
statistics = {}
for ele in list_test:
if ele in statistics:
statistics[ele] += 1
else:
statistics[ele] = 1
for ele, count in statistics.items():
print("%s出现的次数为:%d" % (ele, count))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4.6、循环使用else
Python循环都可以定义else代码块,当循环条件未False时,程序会执行else代码块
num_i = 0
while num_i < 5:
print('小于5', num_i)
num_i += 1
else:
print('大于5', num_i)
- 1
- 2
- 3
- 4
- 5
- 6
4.7、嵌套循环
各种类型的循环都可以作为外层循环,各种类型的循环也都可以作为内层循环
for i in range(0, 3):
j = 0
while j < 3:
print('i的值为:%d,j的值为:%d' % (i, j))
j += 1
- 1
- 2
- 3
- 4
- 5
# i的值为:0,j的值为:0
# i的值为:0,j的值为:1
# i的值为:0,j的值为:2
# i的值为:1,j的值为:0
# i的值为:1,j的值为:1
# i的值为:1,j的值为:2
# i的值为:2,j的值为:0
# i的值为:2,j的值为:1
# i的值为:2,j的值为:2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.8、for表达式
语法格式:
[表达式 for 循环计数器 in 可迭代对象]
- 1
- 在for关键字之前定义一个表达式,该表达式通常会包含循环计数器
- for表达式没有循环体,不需要冒号
for表达式最终返回的是列表,因此也成为列表推导式
a_range = range(10)
a_list = [x * x for x in a_range]
print(a_list) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
- 1
- 2
- 3
还可以在表达式后面添加if判断条件
a_range = range(10)
a_list = [x * x for x in a_range if x % 2 == 0]
print(a_list) # [0, 4, 16, 36, 64]
- 1
- 2
- 3
将for表达式的方括号改为圆括号,for表达式将不再生成列表,而是生成一个生成器(generator)
a_range = range(10)
a_generator = (x * x for x in a_range if x % 2 == 0)
for i in a_generator:
print(i, end='\t')
print() # 0 4 16 36 64
- 1
- 2
- 3
- 4
- 5
4.9、常用工具函数
zip()函数把两个列表“压缩”成一个zip对象(可迭代对象)
books = ['疯狂JAVA讲义', '疯狂Python讲义']
prices = [69, 78]
for book, price in zip(books, prices):
print("%s的价格是:%d" % (book, price))
# 输出结果
# 疯狂JAVA讲义的价格是:69
# 疯狂Python讲义的价格是:78
- 1
- 2
- 3
- 4
- 5
- 6
- 7
reversed()函数:反向遍历
a_range = range(10)
print([x for x in reversed(a_range)]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
- 1
- 2
5、控制循环结构
5.1、使用break结束循环
在某种条件出现时需要中止循环,可以使用break实现。break用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到break,系统将完全结束该循环,执行循环之后的代码。
for i in range(10):
print("i的值是:%d" % i)
if i == 2:
break
else:
print('跳出')
# 输出结果
# i的值是:0
# i的值是:1
# i的值是:2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
break跳出后不会执行循环内容的else语句
5.2、使用continue忽略本次循环的剩下语句
continue只是忽略当次循环的剩下语句,接着进行下一次循环
for i in range(3):
print("i的值是:%d" % i)
if i == 1:
continue
print("结束本次循环!")
# 输出结果
# i的值是:0
# 结束本次循环!
# i的值是:1
# i的值是:2
# 结束本次循环!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
5.3、使用return方法
return语句结束函数、方法、循环等
def test():
for i in range(3):
print("i的值是:%d" % i)
if i == 1:
return
print("结束本次循环!")
test()
# 输出结果
# i的值是:0
# 结束本次循环!
# i的值是:1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
四、函数和lambda表达式
1、函数入门
函数是Python程序的重要组成单位,一个Python程序可以由很多个函数组成。
1.1、理解函数
函数可以接收零个或多个参数,也可以返回零个或多个参数
1.2、定义函数/调用函数
在使用函数之前必须先定义函数,语法格式:
def 函数名(形参列表):
//由零条或者多条可执行语句组成的函数
[return [返回值]]
- 1
- 2
- 3
Python声明函数使用def关键字:
- 函数名:合法的标识符
- 形参列表:形参列表由多个形参名组成,多个形参名之间以英文逗号隔开
def divide(num):
# 将一个浮点类型的数据强制转成int,获取其整数部分内容
int_num = int(num)
float_num = round((num - int_num) * 100)
return (str(int_num), str(float_num))
print(divide(1234)) # ('1234', '0')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
1.3、为函数提供文档
- help()函数
- 函数的__doc__
def divide(num):
"""
divide(num)将一个数据分割其整数/小数部分
:param num:
:return:
"""
# 将一个浮点类型的数据强制转成int,获取其整数部分内容
int_num = int(num)
float_num = round((num - int_num) * 100)
return (str(int_num), str(float_num))
help(divide)
print(divide.__doc__)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
Help on function divide in module __main__:
divide(num)
divide(num)将一个数据分割其整数/小数部分
:param num:
:return:
divide(num)将一个数据分割其整数/小数部分
:param num:
:return:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
1.4、多个返回值
多个返回值时,可以将其封装成列表返回,也可以直接返回多个值,Python自动将多个值封装成元组
def divide(num):
# 将一个浮点类型的数据强制转成int,获取其整数部分内容
int_num = int(num)
float_num = round((num - int_num) * 100)
# return [str(int_num), str(float_num)]
return str(int_num), str(float_num)
print(divide(1235.25)) # ['1235', '25']
print(divide(1235.25)) # ('1235', '25')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1.5、递归函数
在一个函数体内调用它自身,称为递归函数。递归函数包含了一种隐式的循环,重复执行某段代码,但这种重复执行无需循环控制。
举例:
一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n)
def fn(n):
if n == 0:
return 1
elif n == 1:
return 4
else:
return 2*fn(n-1) + fn(n-2)
print(fn(10)) # 10497
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
一个数列:f(20)=1,f(21)=4,f(n+2)=2*f(n+1)+f(n)
def fn(n):
if n == 20:
return 1
elif n == 21:
return 4
else:
return fn(n+2) - 2*fn(n+1)
print(fn(10)) # -3771
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2、函数的参数
2.1、关键字参数
按照形参位置传入的参数被称为位置参数。如果使用位置参数的方式来传入参数值,则需要按照定义函数时指定的参数顺序来传入参数。如果根据参数名来传入参数,则被称之为关键字参数。
def girth(width, height):
return 2 * (width + height)
print(girth(1, 2)) # 6
print(girth(1, height=3)) # 8
print(girth(width=2, height=3)) # 10
print(girth(height=2, width=3)) # 10
- 1
- 2
- 3
- 4
- 5
- 6
关键字参数和位置参数混合使用时,关键字参数必须位于位置参数之后。
2.2、参数默认值
在某些情况下,程序需要在定义函数时为一个或多个形参制定默认值。
格式:
形参名 = 默认值
- 1
若未传入实际参数值,则使用默认值,若传入实际参数值,则使用传入的参数值。
def girth(width, height = 5):
return 2 * ( width + height)
print(girth(1)) # 12
print(girth(1, 3)) # 8
- 1
- 2
- 3
- 4
2.3、参数收集(个数可变的参数)
Python允许在形参前面添加一个(*)号,该参数可接收多个参数值,多个参数值被当成元组传入
def a_test(a, *books):
print(books)
# books被当成元组处理
for i in books:
print(i)
print(a)
a_test(3, '疯狂Java讲义', '疯狂Python讲义')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
# ('疯狂Java讲义', '疯狂Python讲义')
# 疯狂Java讲义
# 疯狂Python讲义
# 3
- 1
- 2
- 3
- 4
如果函数的第一个参数时个数可变的形参,由于该参数可接收个数不等的参数值,则需要给后面的参数传入值时,需要使用关键字参数传值。
def a_test(*books, num):
print(books)
# books被当成元组处理
for i in books:
print(i)
print(num)
a_test('疯狂Java讲义', '疯狂Python讲义', num=5)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Python可收集关键字参数,将关键字参数收集成字典格式。需要在参数前添加两个(*)号。
def a_test(num1, num2, *books, **scores):
print(num1, num2)
print(books)
print(scores)
a_test(2, 3, '疯狂Java讲义', '疯狂Python讲义', 语文=89, 数学=100)
# 2 3
# ('疯狂Java讲义', '疯狂Python讲义')
# {'语文': 89, '数学': 100}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.4、逆向参数收集
指的是在程序已有列表、元组、字典对象的前提下,把他们元素拆开后传给函数的参数
逆向参数收集需要在传入的列表、元组参数之前添加一个* ,在字典参数之前添加两个*。
def a_test(name, message):
print("name是:", name)
print("message:", message)
list_1 = ['ceshi', 'information']
a_test(*list_1)
# name是: ceshi
# message: information
- 1
- 2
- 3
- 4
- 5
- 6
- 7
def a_test(name, *message):
print("name是:", name)
print("message:", message)
tuple_1 = (1, 2, 3)
a_test('tuple', *tuple_1)
# name是: tuple
# message: (1, 2, 3)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
字典也支持逆向收集,将会以关键字参数的形式传入
def b_test(book, price, desc):
print(book, '这本书的价格是:', price, '描述:', desc)
book_info = {'book':'疯狂Python讲义', 'price':69.8, 'desc':'very goog'}
b_test(**book_info) # 疯狂Python讲义 这本书的价格是: 69.8 描述: very goog
- 1
- 2
- 3
- 4
2.5、函数的参数传递机制
Python函数的参数传递机制:“值传递”。即将实际参数的副本(复制品)传入函数,而参数本身是不会受到任何影响的。
def swap(a, b):
a, b = b, a
print("swap函数中:a的值是", a, "b的值是:", b)
a = 3
b = 6
swap(a, b)
print("交换结束后:a的值是", a, "b的值是:", b)
# swap函数中:a的值是 6 b的值是: 3
# 交换结束后:a的值是 3 b的值是: 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
def swap(dw):
dw['a'], dw['b'] = dw['b'], dw['a']
print("swap函数中:a的值是", dw['a'], "b的值是:", dw['b'])
dw = {'a': 6, 'b':9}
swap(dw)
print("交换结束后:a的值是", dw['a'], "b的值是:", dw['b'])
# swap函数中:a的值是 9 b的值是: 6
# 交换结束后:a的值是 9 b的值是: 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.6、变量作用域
局部变量:在函数中定义的变量:参数等
全局变量:函数外面、全局范围内定义的变量
python提供了三个工具函数来获取指定范围内的“变量字典”:
- globals():该函数返回全局范围内所有变量组成的“变量字典”
- locals():该函数返回当前局部范围内所有变量组成的“变量字典”
- vars(object):获取指定对象范围内所有变量组成的“变量字典”,若不传入object,则vars和locals作用相同
def c_test():
name = 'AlySam'
age = 18
print(age) # 18
print(locals()) # {'name': 'AlySam', 'age': 18}
print(locals()['name']) # ALySam
locals()['name'] = 12
print(name) # AlySam
globals()['name'] = 'AlySam_Joe'
c_test()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
全局变量默认可以在所有函数内访问,但如果在函数内定义了与全局变量同名的变量,则会出现局部变量遮蔽全局变量的情况
name = 'AlySam'
def user_info():
name = 'AlySam_Joe'
print(name) # AlySam_Joe
user_info()
- 1
- 2
- 3
- 4
- 5
1、通过globals函数访问被遮蔽的全局变量
name = 'AlySam'
def user_info():
name = 'AlySam_Joe'
print(globals()['name']) # AlySam
user_info()
- 1
- 2
- 3
- 4
- 5
2、在函数中生命全局变量
name = 'AlySam'
def user_info():
# 声明全局变量
global name
name = 'AlySam_Joe'
print(name) # AlySam_Joe
user_info()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3、局部函数
放在函数体内定义的函数—局部函数
在默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭函数内有效,其封闭函数也可以返回局部函数
def get_math_func(type, num):
def square(n):
return n*n
def cube(n):
return n*n*n
if type == 'square':
return square(num)
elif type == 'cube':
return cube(num)
else:
print('请重新输入类型!')
print(get_math_func('square', 3)) # 9
print(get_math_func('cube', 3)) # 27
print(get_math_func('square_cube', 3)) # 请重新输入类型!
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
Python提供nonlocal函数,通过nonlocal语句可声明访问语句只是访问该函数所在函数内的局部变量
def foo():
name = 'ALySam'
def bar():
nonlocal name
print(name) # name = 'AAA'
name = 'AAA'
bar()
foo()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
4、函数高级内容
函数本身也是一个对象,函数既可以用于赋值,也可以用作其他函数的参数。
4.1、使用函数变量
函数也是function对象,因此可以把函数本身赋值给变量,类似于把整数、浮点数、列表、元组赋值给变量一样
def pow(base, exponent):
result = 1
for i in range(1, exponent + 1):
result *= base
return result
# print(pow(2, 5)) # 32
# 将函数赋值给变量,该变量可被当成函数使用
my_fun = pow
print(my_fun(2, 5)) # 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.2、使用函数作为函数形参
调用函数时传入不同的函数作为参数
# 定义函数类型的形参,其中fn是一个函数
def map(data, fn):
result = []
# 遍历data中的每个元素,并用fn函数对每个元素进行计算
# 将计算结果作为新数组的元素
for e in data:
result.append(fn(e))
return result
# 定义一个计算平方的函数
def square(n):
return n * n
# 定义一个计算立方的函数
def cube(n):
return n * n * n
# 定义一个计算阶乘的函数
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
data = [3, 4, 9, 5, 8]
print("原数据为:{0}".format(data))
print(map(data, square))
print(map(data, cube))
print(map(data, factorial))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
# 原数据为:[3, 4, 9, 5, 8]
# [9, 16, 81, 25, 64]
# [27, 64, 729, 125, 512]
[6, 24, 362880, 120, 40320]
- 1
- 2
- 3
- 4
4.3、使用函作为返回值
使用函数作为其他函数的返回值
def get_math_func(type):
# 定义一个计算平方的函数
def square(n):
return n * n
# 定义一个计算立方的函数
def cube(n):
return n * n * n
# 定义一个计算阶乘的函数
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
# 返回局部函数
if type == 'square':
return square
elif type == 'cube':
return cube
else:
return factorial
math_func = get_math_func('square')
print(math_func(5)) # 25
math_func = get_math_func('cube')
print(math_func(5)) # 125
math_func = get_math_func('factorial')
print(math_func(5)) # 120
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
5、局部函数与lambda表达式
lambda表达式是比较灵活的代码块,可以在程序中被传递和调用
5.1、回顾局部函数
def get_math_func(type):
# 定义三个局部函数
...
# 返回局部函数
if type == 'square':
return square
elif type == 'cube':
return cube
else:
return factorial
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
5.2、使用lambda表达式替代局部函数
def get_math_func(type):
result = 1
# 该函数返回lambda表达式
if type == 'square':
return lambda n: n * n
elif type == 'cube':
return lambda n: n * n * n
else:
return lambda n: (1 + n ) * n / 2
math_func = get_math_func('square')
print(math_func(5)) # 25
math_func = get_math_func('cube')
print(math_func(5)) # 125
math_func = get_math_func('factorial')
print(math_func(5)) # 120
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
Python要求lambda表达式只能是单行表达式
lambda表达式的语法格式:
lambda [parameter_list]:表达式
- 1
- lambda表达式必须使用lambda关键字
- 在lambda关键字之后、冒号左边的是参数列表可以是一个参数也可以由多个参数。如果有多个参数,则需要用逗号隔开,冒号右边是该lambda表达式的返回值
lambda x,y:x+y
def add(x,y): return x+y
- 1
- 2
五、类和对象
1、类和对象
类是面向对象的重要内容,可以把类当成一种自定义类型,可以使用类来定义变量,也可以使用类来创建对象。
1.1、定义类
类(class)、对象(object,也被称为实例instance),类是某一批对象的抽象,可以把类理解个某种概念;对象才是一个具体存在的实体
class 类名:
执行语句..
零个到多个类变量...
零个到多个方法...
- 1
- 2
- 3
- 4
类名只要是一个合法的标识符即可,从程序的可读性方面来看,类名必须是由一个或多个有意义的单词组成,每个单词首字母大写,其他小写且单词之间不使用任何分隔符。
类定义由类头和统一缩进的类体构成。在类体中最主要的两个成员就是类变量和方法。
空类定义如下:
class Empty:
pass
- 1
- 2
Python类中所包含的最重要的两个成员为变量和方法,其中类变量属于类本身,用于定义该类本身所包含的状态数据;而实例变量则属于该类的对象,用于定义对象所包含的状态数据;方法则用于定义该类的对象的行为或功能实现。
在类中定义的方法默认的是实例方法,定义实例方法与定义函数的方法基本相同,只是实例方法的第一个参数会被绑定到方法的调用者(该类的实例),因此实例方法至少应该定义一个参数,该参数通常会被命名为self。
在实例方法中有一个特别的方法。init(构造方法)。构造方法用于构造该类的对象,Python通过调用构造方法返回该类的对象。
class Person:
hair = 'black'
def __init__(self, name = 'AlySam', age = '18'):
# 为Python对象添加两个实例变量
self.name = name
self.age = age
def say(self, content):
print(content)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1.2、对象的产生和使用
创建对象的根本途径是构造方法,调用某个类的构造方法即可创建这个类的对象
p = Person()
print(p.name) # AlySam
- 1
- 2
在创建对象后,使用对象:
- 操作对象的实例变量(包括访问实例变量的值、添加实例变量、删除实例变量)
- 操作对象的方法(包括调用方法、添加方法、删除方法)
对象访问变量/方法的语法:对象.变量/方法(参数)
class Person:
hair = 'black'
def __init__(self, name = 'AlySam', age = '18'):
self.name = name
self.age = age
def say(self, content):
print(content)
p = Person()
# 访问实例变量,直接为变量赋值
p.name = 'AlySam_Joe'
print(p.name, p.age) # AlySam_Joe 18
print(p.hair) # black
p.say('You are so coll!') # You are so coll!
print(p.name) # AlySam_Joe
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
1.3、对象的动态性
程序可以为对象动态的增加、删除实例变量
# 为对象添加实例变量
p.skills = ['swimming', 'singing']
print(p.skills) # ['swimming', 'singing']
# 删除对象某个实例变量
del p.age
print(p.age) # AttributeError: 'Person' object has no attribute 'age'
- 1
- 2
- 3
- 4
- 5
- 6
为对象动态增加方法,需要说明:为对象动态添加的方法,Python不会自动将调用者自动绑定到第一个参数(即使将第一个参数命名为self也没用)。
class Person:
hair = 'black'
def __init__(self, name = 'AlySam', age = '18'):
self.name = name
self.age = age
def say(self, content):
print(content)
p = Person()
def info(self):
print("----info函数----", self)
# 使用info对p的foo方法赋值(动态增加方法)
p.foo = info
# 需要手动将调用者绑定到第一个参数
p.foo(p)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
自动绑定第一个参数:types 模块下 MethodType函数
from types import MethodType
class Person:
hair = 'black'
def __init__(self, name = 'AlySam', age = '18'):
self.name = name
self.age = age
def say(self, content):
print(content)
p = Person()
def info(self, content):
print("----info函数----: %s" % content)
# 使用info对p的foo方法赋值(动态增加方法)
p.foo = MethodType(info, p)
p.foo("SSS") # ----info函数----: SSS
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
1.4、实例方法和自动绑定self
self参数最大的作用就是引用当前方法的调用者
class Dog:
def jump(self):
print("--jump--")
def run(self):
# 使用self参数引用调用run()方法的对象
self.run()
print("--run--")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在构造方法中,self参数代表该构造方法正在初始化的对象。
class InConstructor:
def __init__(self):
# 在构造方法中定义一个foo变量
foo = 0
# 使用self代表该构造方法正在初始化的对象
self.foo = 6
print(InConstructor().foo) # 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2、方法
2.1、类也能调用实例方法
def foo():
print("--foo--")
bar = 20
class Brid:
def foo():
print("--class--foo--")
bar = 'class_num'
foo() # Brid.foo
print(bar) # 20
Brid.foo() # --class--foo--
print(Brid.bar) # class_num
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
class User:
def walk(self):
print('--walk--')
u = User()
User.walk(u) # --walk--
- 1
- 2
- 3
- 4
- 5
2.2、类方法与静态方法
类方法与静态方法的区别:Python会自动绑定类方法的第一个参数,类方法的第一个参数(cls)
会自动绑定到类本身;静态方法则不会自动绑定。
使用@classmethod修饰的是类方法、使用@staticmethod修饰的是静态方法
class Bird:
@classmethod
def fly(cls):
print("类方法fly:", cls)
@staticmethod
def info(p):
print("静态方法info:", p)
# 调用类方法,类会自动绑定到第一个参数
Bird.fly()
# 调用静态方法,不会自动绑定,需要手动绑定其第一个参数
Bird.info('JingTai') # 类方法fly: <class '__main__.Bird'>
b = Bird() # 静态方法info: JingTai
b.fly() # 类方法fly: <class '__main__.Bird'>
b.info('JingTai') # 静态方法info: JingTai
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2.3、@函数装饰器(还需进一步学习)
@classmethod和@staticmethod的本质都是函数装饰器,其中staticmethod、classmethod都是Python的内置函数。使用@符号引用已有的函数后,用于修饰其他函数
def funA(fn):
print("A")
# 执行传入的fn参数
fn()
return 'AAA'
"""
1、将funB作为funA的参数
2、将funB替换成①执行完的结果,funA执行完返回字符串,因此funB就不再是函数,而是被装饰成一个字符串
"""
@funA
def funB():
print("B")
print(funB)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.4、再论类命名空间
global_fn = lambda p: print("执行lambda表达式,p参数:", p)
class Category:
cate_fn = lambda p: print("执行lambda表达式,p参数:", p)
# 执行全局空间内的global_fn
global_fn('Global_AAA') # 执行lambda表达式,p参数: Global_AAA
c = Category()
c.cate_fn() # 执行lambda表达式,p参数: <__main__.Category object at 0x000002988745CFA0>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3、成员变量
在类体内定义的变量,默认属于类本身。如果把类当成类命名空间,该类变量其实就是定义在类命名空间内的变量
3.1、类变量和实例变量
类变量:在类命名空间内定义的变量就属于类变量,Python可以使用类来读取、修改类变量。
不管在全局范围内还是函数内访问这些类变量,都必须使用类名进行访问。
class Address:
# 定义两个类变量
detail = '广州'
post_code = '510660'
def info(self):
# 使用类名进行访问
print(Address.detail)
print(Address.post_code)
print(Address.detail) # 广州
addr = Address()
addr.info()
Address.detail = '佛山'
Address.post_code = '460110'
addr.info()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
使用对象来访问该对象所属类的类变量
class Address:
detail = '广州'
post_code = '510660'
def info(self):
# 使用对象来访问该对象所属类的类变量
print(self.detail)
print(self.post_code)
addr = Address()
addr.info()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
3.2、使用property函数定义属性
如果为Python类定义了getter、setter等访问器方法,则可以使用property()函数将他们定义属性(相当于实例变量)
property()函数语法格式:
property(fget=None, fset=None, fdel=None, doc=None)
- 1
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def setsize(self, size):
self.width, self.height = size
def getsize(self):
return self.width, self.height
def delsize(self):
self.width, self.height = 0, 0
size = property(getsize, setsize, delsize, '用于描述矩形大小的属性')
print(Rectangle.size.__doc__)
# help(Rectangle.size)
rect = Rectangle(4, 3)
print(rect.size)
rect.size = 9, 7
print(rect.width) # 9
print(rect.height) # 7
del rect.size
print(rect.width) # 0
print(rect.height) # 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
4、隐藏和封装(还需进一步学习)
封装是面向对象的三大特征之一(继承/多态),指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
将Python类的成员命名为以双下划綫开头的,Python将其隐藏起来
class User:
def __hide(self):
print('示范隐藏的hide方法')
def getname(self):
return self.__name
def setname(self, name):
if len(name) < 3 or len(name) > 8:
raise ValueError('用户名长度必须在3~8之间')
self.__name = name
name = property(getname, setname)
def setage(self, age):
if age < 18 or age > 70:
raise ValueError('年龄必须在18-70之间')
self.__age = age
def getage(self):
return self.__age
age = property(getage, setage)
user = User()
user.name = 'AlySam'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
5、类的继承
5.1、继承的语法
Python子类继承父类的语法是在定义子类时,将多个父类放在子类之后的圆括号中,语法格式:
class SubClass(SuperClass1, SuperClass2,...):
# 类定义部分
- 1
- 2
在定义一个Python类时并未指定这个类的直接父类,则这个类默认继承object类。object类是所有类的父类,要么是直接父类,要么是间接父类。
实现继承的类被称为子类,被继承的类称为父类(基类、超类)。子类是一种特殊的父类,因此父类包含的范围总比子类的范围大。
class Fruit:
def info(self):
print('我是一个水果!重%g克' % self.weight)
class Food:
def taste(self):
print('不同食物的口感不同')
# 定义Apple类,继承了Fruit/Food类
class Apple(Fruit, Food):
pass
a = Apple()
a.weight = 5.6
a.info()
a.taste()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
5.2、关于多继承
当一个子类有多个直接父类时,该子类会继承得到所有父类的方法。但如果多个父类中包含了同名的方法,则排在前面的父类的方法会“遮蔽”后面父类中的同名方法
class Fruit:
def info(self):
print('我是一个水果!重%g克' % self.weight)
class Food:
def info(self):
print('不同食物的口感不同')
# 定义Apple类,继承了Fruit/Food类
class Apple(Fruit, Food):
pass
a = Apple()
a.weight = 5.6
a.info() # 我是一个水果!重5.6克
class Apple(Food, Fruit):
pass
a = Apple()
a.info() # 不同食物的口感不同
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
5.3、重写父类的方法
子类扩展了父类,子类是一种特殊的父类。大多时候,子类是以父类为基础,额外增加新的方法。但也有种情况,针对某种特殊情况,需要重写父类的方法。(子类包含与父类同名的方法/子类覆盖了父类的方法)
class Brid:
def fly(self):
print("在天空中自由自在地飞翔...")
class Ostrich(Brid):
def fly(self):
print('鸵鸟只能在地上奔跑')
os = Ostrich()
os.fly() # 鸵鸟只能在地上奔跑
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5.4、使用未绑定方法调用被重写的方法
需要在子类中调用父类中被重写的实例方法(需要程序显式绑定第一个参数self:未绑定方法)
通过使用未绑定方法即可在子类中再次调用父类中被重写的方法
class Brid:
def fly(self):
print("在天空中自由自在地飞翔...")
class Ostrich(Brid):
def fly(self):
print('鸵鸟只能在地上奔跑')
# 使用类名调用实例方法(未绑定方法)调用父类被重写的方法
def fly_Super(self):
Brid.fly(self)
os = Ostrich()
os.fly() # 鸵鸟只能在地上奔跑
os.fly_Super() # 在天空中自由自在地飞翔...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12