2022年 11月 7日

Python疯狂讲义学习(变量、列表、元组、字典、流程、函数、类与对象)

文章目录

  • 一、变量和简单类型
    • 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是弱类型语言,有两个典型特征:

  1. 变量无需声明可直接赋值:对一个不存在的变量赋值就相当于定义了一个新变量;
  2. 变量的数据类型可动态改变:同一个变量可以一会儿被赋值为整数值,一会儿被赋值为字符串;

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、变量的命名规则

  1. 标识符可以由字母、数字、下划线(_)组成,其中不能以数字开头;
  2. 标识符不能是Python关键字,但可以包含关键字;
  3. 标识符不能包含空格;

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
  1. 十进制形式:
  2. 二进制形式:以0b/0B开头的整数
  3. 八进制形式:以0o/0O开头的整数
  4. 十六进制形式:以0x/0X开头的整数

Python允许数值(包括浮点型)增加下划线作为分隔符

one_million = 1_000_000
print(one_million)			# 1000000
  • 1
  • 2

3.2、浮点型(float)

  1. 十进制形式:5.12
  2. 科学计数形式: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、字符串/转义字符

字符串可以使用单引号括起来,也可以使用双引号括起来。如果字符串本身包含了单/双引号,需要进行特殊处理

  1. 使用不同的引号将字符串括起来
  2. 对引号进行转义
# 字符串 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对象:

  1. 如果字符串内容都是ASCII字符,则可以通过直接在字符串前加b来构建;
  2. 调用bytes函数
  3. 调用字符串本身的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
  1. -:指定左对齐;
  2. +:表示数值总是要呆着符号(正数:+;负数:-);
  3. 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、大小写相关方法

两个帮助函数:

  1. dir():列出指定类或模块包含的全部内容
  2. help():查看某个函数或方法的帮助文档

相关函数介绍:

  1. title():将每个单词的首字母改为大写;
  2. lower():将整个字符串改为小写;
  3. 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、删除空白

方法说明:

  1. strip():删除字符串前后的空白
  2. lstrip():删除字符串前面(左边)的空白
  3. 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、查找/替换相关方法

方法说明:

  1. startwith():判断字符串是否已指定字符开头
  2. endwith():判断字符串是否已指定字符结尾
  3. find():查找子串在字符串中出现的位置,如没有找到指定子串,返回-1
  4. index():查找子串在字符串中出现的位置,如没有找到指定子串,引发ValueError错误
  5. replace():使用指定的子串代替字符串中的目标字串
  6. 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、分割/连接方法

方法说明:

  1. split():将字符串按指定分割符分割成多个短语
  2. 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、运算符

种类:

  1. 赋值运算符
  2. 算数运算符
  3. 位运算符
  4. 索引运算符
  5. 比较运算符
  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个

  1. &:按位与
  2. |:按位或
  3. ^:按位异或
  4. ~:按位取反
  5. “<<”:左位移运算符
  6. “>>”:右位移运算符

6.4、扩展后的赋值运算符

  1. +=
  2. -=
  3. *=
  4. /=
  5. //=
  6. %=
  7. **=
  8. &=
  9. |=
  10. ^=
  11. <<= >>=

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值。

  1. and:与 前后两个操作数都必须是True才返回True;
  2. or:或 两个操作数中有一个操作数为True时返回True;
  3. 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)的功能
两种赋值形式:

  1. 程序把多个值赋值给一个变量时,Python会自动将多个值封装成元组;(序列封包)
  2. 程序允许将(元组/列表)直接赋值给多个变量,此时序列的各元素会依次赋值给每个变量(要求序列的元素个数和变量个数相等);(序列解包)
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’]

常用方法说明:

  1. count():统计列表中某个元素出现的次数
  2. index():判断列表中某个元素出现的位置
  3. pop():将列表当成“栈”使用,实现元素出栈功能
  4. reverse():将列表中的元素反向存放
  5. 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、字典的基本用法

  1. 通过key访问value
  2. 通过key添加key-value对
  3. 通过key删除key-value对
  4. 通过key修改key-value对
  5. 通过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处理

FalseNone0""()[]{}
  • 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部分内容:

  1. 初始化语句:
  2. 循环条件:
  3. 循环体:
  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
  1. for-in循环中的变量的值受for-in循环控制,该变量将会在每次循环开始时自动被赋值;
  2. 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循环遍历字典

  1. items():返回字典中所有key-value对的列表
  2. keys():返回字典中所有key的列表
  3. 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
  1. 在for关键字之前定义一个表达式,该表达式通常会包含循环计数器
  2. 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关键字:

  1. 函数名:合法的标识符
  2. 形参列表:形参列表由多个形参名组成,多个形参名之间以英文逗号隔开
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、为函数提供文档

  1. help()函数
  2. 函数的__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提供了三个工具函数来获取指定范围内的“变量字典”:

  1. globals():该函数返回全局范围内所有变量组成的“变量字典”
  2. locals():该函数返回当前局部范围内所有变量组成的“变量字典”
  3. 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
  1. lambda表达式必须使用lambda关键字
  2. 在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

在创建对象后,使用对象:

  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