python学习

类型
python
学习时间
Jun 28, 2019
状态
完成
参考资料
封面
44f287e3a0f7e6978eab381f49312f71.jpeg

Python

python开发环境搭建

Python 解释器

Python解释器作⽤:运⾏文件
Python解释器种类
  • CPython,C语⾔开发的解释器[官⽅],应⽤⼴泛的解释器
  • IPython,基于CPython的⼀种交互式解释器
  • 其他解释器
    • PyPy,基于Python语言开发的解释器
    • Jython,运行在java平台的解释器,直接把Python代码编译成java字节码执行
    • IronPython,运⾏在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

下载Python解释器

[单击上述链接] -- 查找⽬目标⽂文件:Windows x86-64 executable installer -- 单击即可下载。
notion image

安装Python解释器

notion image
注意安装时候将python解释器加到PATH变量

安装IDE PyCharm

PyCharm基本使用
打开PyCharm -- [Create New Project] -- 选择项⽬根⽬录和解释器版本 -- [Create],即可完成新建⼀一 个项⽬
notion image

Python基本语法

注释的分类及语法

注释分为两类:单⾏注释 和 多行注释。
  • 单⾏注释
只能注释⼀行内容,语法如下:
# 注释内容
  • 多⾏行行注释
  • 可以注释多行内容,⼀般用在注释一段代码的情况, 语法如下
""" 第⼀一⾏行行注释 第⼆二⾏行行注释 第三⾏行行注释 """ ''' 注释1 注释2 注释3 '''

变量

变量量名 = 值
变量量名⾃自定义,要满⾜足标识符命名规则。

标识符

标识符命名规则是Python中定义各种名字的时候的统⼀规范,具体如下
  • 由数字、字⺟、下划线组成
  • 不能数字开头
  • 不能使⽤用内置关键字
  • 严格区分大小写
内置关键字
False None continue def from not yield True and del global if or as elif pass raise else import in assert break return try lambda while class except finally for is nonlocal with

命名习惯

  • 见名知义。
  • ⼤大驼峰:即每个单词首字母都大写,例如: MyName 。
  • 小驼峰:第⼆个(含)以后的单词⾸字⺟⼤写,例如: myName 。
  • 下划线:例如: my_name 。

数据类型

notion image
image-20201204104740151
检测数据类型的⽅方法: type()
例:
a = 1 print(type(a)) # <class 'int'> -- 整型 b = 1.1 print(type(b)) # <class 'float'> -- 浮点型 c = True print(type(c)) # <class 'bool'> -- 布尔型 d = '12345' print(type(d)) # <class 'str'> -- 字符串 e = [10, 20, 30] print(type(e)) # <class 'list'> -- 列列表 f = (10, 20, 30) print(type(f)) # <class 'tuple'> -- 元组 h = {10, 20, 30} print(type(h)) # <class 'set'> -- 集合 g = {'name': 'TOM', 'age': 20} print(type(g)) # <class 'dict'> -- 字典

输入输出

输出

输出:程序输出内容给⽤用户
print('hello Python') age = 18 print(age) # 需求:输出“今年我的年龄是18岁”
格式化输出
所谓的格式化输出即按照⼀定的格式输出内容。
格式化符号
格式符号
字符串
字符串
有符号的十进制整数
浮点数
字符
无符号十进制整数
八进制整数
十六进制整数(小写ox)
⼗六进制整数(大写OX)
科学计数法(⼩小写'e')
科学计数法(⼤大写'E')
%f和%e的简写
%f和%E的简写
  • %06d,表示输出的整数显示位数,不足以0补全,超出当前位数则原样输出
  • %.2f,表示小数点后显示的小数位数
格式化字符串串除了了%s,还可以写为 f'{表达式}'
age = 18 name = 'TOM' weight = 75.5 student_id = 1 # 我的名字是TOM print('我的名字是%s' % name) # 我的学号是0001 print('我的学号是%4d' % student_id) # 我的体重是75.50公⽄斤 print('我的体重是%.2f公⽄斤' % weight) # 我的名字是TOM,今年年18岁了了 print('我的名字是%s,今年年%d岁了了' % (name, age)) # 我的名字是TOM,明年年19岁了了 print('我的名字是%s,明年年%d岁了了' % (name, age + 1)) # 我的名字是TOM,明年年19岁了了 print(f'我的名字是{name}, 明年年{age + 1}岁了了')
f-格式化字符串是Python3.6中新增的格式化方法,该⽅法更简单易读
转义字符
  • \n :换⾏行行。
  • \t :制表符,⼀个tab键(4个空格)的距离
在Python中,print(), 默认自带 end="\n" 这个换⾏结束符,所以导致每两个 print 直接会换行展示,⽤户可以按需求更改结束符
print('输出的内容', end=" ")

输入

在Python中,程序接收用户输入的数据的功能即是输入。
input("提示信息")
输入的特点
  • 当程序执⾏到 input ,等待用户输入,输入完成之后才继续向下执行。
  • 在Python中, input 接收⽤用户输入后,⼀般存储到变量,⽅便使⽤。
  • 在Python中, input 会把接收到的任意⽤户输入的数据都当做字符串处理
password = input('请输⼊入您的密码:') print(f'您输⼊入的密码是{password}') # <class 'str'> print(type(password))

数据类型转换

转换数据类型的函数
函数
说明
将x转换为一个整数
将x转换为⼀个浮点数
创建⼀个复数,real为实部,imag为虚部
将对象 x 转换为字符串
将对象 x 转换为表达式字符串
⽤来计算在字符串中的有效Python表达式,并返回一个对象
将序列 s 转换为一个元组
将序列 s 转换为一个列列表
将⼀个整数转换为一个Unicode字符
将⼀个字符转换为它的ASCII整数值
将⼀个整数转换为一个⼗六进制字符串
将⼀个整数转换为⼀个八进制字符串
将⼀个整数转换为⼀个⼆进制字符串
案例
# 1. 接收⽤用户输⼊入 num = input('请输⼊入您的幸运数字:') # 2. 打印结果 print(f"您的幸运数字是{num}") # 3. 检测接收到的⽤用户输⼊入的数据类型 -- str类型 print(type(num)) # 4. 转换数据类型为整型 -- int类型 print(type(int(num))) # 1. float() -- 转换成浮点型 num1 = 1 print(float(num1)) print(type(float(num1))) # 2. str() -- 转换成字符串串类型 num2 = 10 print(type(str(num2))) # 3. tuple() -- 将⼀一个序列列转换成元组 list1 = [10, 20, 30] print(tuple(list1)) print(type(tuple(list1))) # 4. list() -- 将⼀一个序列列转换成列列表 t1 = (100, 200, 300) print(list(t1)) print(type(list(t1))) # 5. eval() -- 将字符串串中的数据转换成Python表达式原本类型 str1 = '10' str2 = '[1, 2, 3]' str3 = '(1000, 2000, 3000)' print(type(eval(str1))) print(type(eval(str2))) print(type(eval(str3)))

运算符

  • 算数运算符
  • 赋值运算符
  • 复合赋值运算符
  • ⽐较运算符
  • 逻辑运算符
算数运算符
运算符
描述
实例
1 + 1 输出结果为 2
1-1 输出结果为 0
2 * 2 输出结果为 4
10 / 2 输出结果为 5
整除
9 // 4 输出结果为2
取余
9 % 4 输出结果为 1
指数
2 ** 4 输出结果为 16,即 2 * 2 * 2 * 2
小括号
⼩括号⽤来提⾼运算优先级,即 (1 + 2) * 3 输出结果为 9
混合运算优先级顺序: () ⾼高于 ** ⾼高于 * / // % ⾼高于 + -
赋值运算符
运算符
描述
实例
赋值
将 = 右侧的结果赋值给等号左侧的变量
加法赋值运算符
c += a 等价于 c = c + a
减法赋值运算符
c -= a 等价于 c = c- a
乘法赋值运算符
c *= a 等价于 c = c * a
除法赋值运算符
c /= a 等价于 c = c / a
整除赋值运算符
c //= a 等价于 c = c // a
取余赋值运算符
c %= a 等价于 c = c % a
幂赋值运算符
c ** = a 等价于 c = c ** a
⽐较运算符
⽐较运算符也叫关系运算符, 通常⽤来判断
运 算 符
描述
实例
判断相等。如果两个操作数的结果相等,则条件结 果为真(True),否则条件结果为假(False)
如a=3,b=3,则(a == b) 为 True
不等于 。如果两个操作数的结果不相等,则条件为真(True),否则条件结果为假(False)
如a=3,b=3,则(a == b) 为 True如 a=1,b=3,则(a != b) 为 True
运算符左侧操作数结果是否大于右侧操作数结果, 如果大于,则条件为真,否则为假
如a=7,b=3,则(a > b) 为 True
运算符左侧操作数结果是否小于右侧操作数结果, 如果小于,则条件为真,否则为假
如a=7,b=3,则(a < b) 为 False
运算符左侧操作数结果是否大于等于右侧操作数结 果,如果大于,则条件为真,否则为假
如a=7,b=3,则(a < b) 为 False如 a=3,b=3,则(a >= b) 为 True
运算符左侧操作数结果是否小于等于右侧操作数结 果,如果小于,则条件为真,否则为假
如a=3,b=3,则(a <= b) 为 True
逻辑运算符
运 算 符
逻辑表达式
描述
实例
x and y
布尔"与":如果 x 为 False,x and y 返回 False,否则它返回 y 的值。
True and False, 返回 False
x or y
布尔"或":如果 x 是 True,它返回 True,否则 它返回 y 的值。
False or True, 返回 True。
not x
布尔"⾮非":如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。
not True 返回 False, not False 返回 True
数字之间的逻辑运算
a = 0 b = 1 c = 2 # and运算符,只要有⼀个值为0,则结果为0,否则结果为最后⼀一个非0数字 print(a and b) # 0 print(b and a) # 0 print(a and c) # 0 print(c and a) # 0 print(b and c) # 2 print(c and b) # 1 # or运算符,只有所有值为0结果才为0,否则结果为第⼀个⾮0数字 print(a or b) # 1 print(a or c) # 2 print(b or c) # 1

条件语句

if 语法

if 条件: 条件成⽴立执⾏行行的代码 ......
age = 20 if age >= 18: print('已经成年年,可以上⽹网') print('系统关闭')

if...else语句

if 条件: 条件成⽴立执⾏行行的代码1 条件成⽴立执⾏行行的代码2 ...... else: 条件不不成⽴立执⾏行行的代码1 条件不不成⽴立执⾏行行的代码2 ......

多重判断

if 条件1: 条件1成⽴立执⾏行行的代码1 条件1成⽴立执⾏行行的代码2 ...... elif 条件2: 条件2成⽴立执⾏行行的代码1 条件2成⽴立执⾏行行的代码2 ...... else: 以上条件都不不成⽴立执⾏行行执⾏行行的代码
age = int(input('请输⼊入您的年年龄:')) if age < 18: print(f'您的年年龄是{age},童⼯工⼀一枚') elif age >= 18 and age <= 60: print(f'您的年年龄是{age},合法⼯工龄') elif age > 60: print(f'您的年年龄是{age},可以退休')
age >= 18 and age <= 60可以化简为18 <= age <= 60

if嵌套

if 条件1: 条件1成⽴立执⾏行行的代码 条件1成⽴立执⾏行行的代码 if 条件2: 条件2成⽴立执⾏行行的代码 条件2成⽴立执⾏行行的代码
""" 1. 如果有钱,则可以上⻋车 2. 上⻋车后,如果有空座,可以坐下 上⻋车后,如果没有空座,则站着等空座位 如果没钱,不不能上⻋车 """ # 假设⽤用 money = 1 表示有钱, money = 0表示没有钱; seat = 1 表示有空座,seat = 0 表示 没有空座 money = 1 seat = 0 if money == 1: print('⼟土豪,不不差钱,顺利利上⻋车') if seat == 1: print('有空座,可以坐下') else: print('没有空座,站等') else: print('没钱,不能上⻋车,追着公交⻋车跑')

三目运算符

条件成⽴执⾏的表达式 if 条件 else 条件不成⽴执⾏的表达式
a = 1 b = 2 c = a if a > b else b print(c)

循环

while

while 条件: 条件成⽴重复执⾏的代码1 条件成⽴重复执⾏的代码2 ......
i = 1 result = 0 while i <= 100: result += i i += 1 # 输出5050 print(result)

break和continue

break和continue是循环中满⾜一定条件退出循环的两种不同⽅式。
i = 1 while i <= 5: if i == 4: print(f'吃饱了了不不吃了了') break print(f'吃了了第{i}个苹果') i += 1 i = 1 while i <= 5: if i == 3: print(f'⼤大⾍虫⼦子,第{i}个不不吃了了') # 在continue之前⼀一定要修改计数器器,否则会陷⼊入死循环 i += 1 continue print(f'吃了了第{i}个苹果') i += 1

while循环嵌套

while 条件1: 条件1成⽴立执⾏行行的代码 ...... while 条件2: 条件2成⽴立执⾏行行的代码 ......
99乘法表
# 重复打印9⾏行行表达式 j = 1 while j <= 9: # 打印⼀一⾏行行⾥里里⾯面的表达式 a * b = a*b i = 1 while i <= j: print(f'{i}*{j}={j*i}', end='\t') i += 1 print() j += 1

for循环

for 临时变量 in 序列列: 重复执⾏行行的代码1 重复执⾏行行的代码2 ...... str1 = 'hello,world!' for i in str1: print(i)

循环配合else

循环可以和else配合使⽤,else下⽅缩进的代码指的是当循环正常结束之后要执⾏的代码。
i = 1 while i <= 5: if i == 3: print('这遍说的不真诚') break print('媳妇⼉,我错了了') i += 1 else: print('媳妇原谅我了,真开⼼,哈哈哈哈')
循环break ,else代码不执行
i = 1 while i <= 5: if i == 3: print('这遍说的不不真诚') i += 1 continue print('媳妇⼉儿,我错了了') i += 1 else: print('媳妇原谅我了了,真开⼼心,哈哈哈哈')
循环中间有一次continue,else代码会执行
for 和 else 也是类似结果

字符串

定义

字符串是 Python 中最常⽤的数据类型。我们⼀般使⽤引号来创建字符串。创建字符串很简单,只要为变量分配⼀个值即可。
a = 'hello world' b = "abcdefg" print(type(a)) print(type(b))
字符串单引号和双引号都可以
一对引号字符串
name1 = 'Tom' name2 = "Rose"
三引号字符串
name3 = ''' Tom ''' name4 = """ Rose """ a = ''' i am Tom, nice to meet you! ''' b = """ i am Rose, nice to meet you! """ c = "I'm Tom" d = 'I\'m Tom'
三引号形式的字符串支持换⾏

下标

name = "abcdef" print(name[1])# b print(name[0])# a print(name[2])# c

切⽚

切⽚是指对操作的对象截取其中⼀部分的操作。字符串、列表、元组都⽀持切⽚操作
语法: 序列[开始位置下标:结束位置下标:步长]
注意 :
  1. 不包含结束位置下标对应的数据, 正负整数均可;
  1. 步长是选取间隔,正负整数均可,默认步长为1
name = "abcdefg" print(name[2:5:1]) # cde print(name[2:5]) # cde print(name[:5]) # abcde print(name[1:]) # bcdefg print(name[:]) # abcdefg print(name[::2]) # aceg print(name[:-1]) # abcdef, 负1表示倒数第⼀一个数据 print(name[-4:-1]) # def print(name[::-1]) # gfedcba

查找

所谓字符串查找方法即是查找子串在字符串中的位置或出现的次数。
find():检测某个⼦串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,否则返回-1。
语法: 字符串串序列列.find(⼦子串串, 开始位置下标, 结束位置下标)
注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找。
mystr = "hello world and itcast and itheima and Python" print(mystr.find('and')) # 12 print(mystr.find('and', 15, 30)) # 23 print(mystr.find('ands')) # -1
index():检测某个子串是否包含在这个字符串中,如果在返回这个⼦串开始的位置下标,否则报异常
语法: 字符串序列.index(⼦串, 开始位置下标, 结束位置下标)
注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找修改
mystr = "hello world and USA and UK and Python" print(mystr.index('and')) # 12 print(mystr.index('and', 15, 30)) # 20 print(mystr.index('ands')) # 23
其他查询函数
  • rfind(): 和find()功能相同,但查找⽅向为右侧开始。
  • rindex():和index()功能相同,但查找⽅向为右侧开始。
  • count():返回某个子串在字符串中出现的次数

修改

所谓修改字符串,指的就是通过函数的形式修改字符串中的数据
  • replace():替换
  • 1 语法 : 字符串序列.replace(旧⼦串, 新⼦串, 替换次数)
    • 注意:替换次数如果查出⼦串出现次数,则替换次数为该⼦串出现次数
      案例
      mystr = "hello world and USA and UK and Python" print(mystr.replace('and', 'or', 1)) # hello world or USA and UK and Python print(mystr.replace('and', 'or')) # hello world or USA or UK or Python print(mystr.replace('and', 'or', 10)) # hello world or USA or UK or Python print(mystr) # hello world and USA and UK and Python
      注意:数据按照是否能直接修改分为可变类型和不可变类型两种。字符串类型的数据修改的时候不能改变原有字符串,属于不能直接修改数据的类型即是不可变类型
  • split(): 按照指定字符分割字符串。
      1. 语法 字符串序列.split(分割字符, num)
    • 注意:num表示的是分割字符出现的次数,即将来返回数据个数为num+1个
      • mystr = "hello world and USA and UK and Python" print(mystr.split('and', 1)) # ['hello world ', ' USA and UK and Python'] print(mystr.split('and', 2)) # ['hello world ', ' USA ', ' UK and Python'] print(mystr.split('and')) # ['hello world ', ' USA ', ' UK ', ' Python'] print(mystr.split(' ')) # ['hello', 'world', 'and', 'USA', 'and', 'UK', 'and', 'Python']
        注意:如果分割字符是原有字符串中的⼦串,分割后则丢失该⼦串。
  • join():⽤一个字符或⼦串合并字符串,即是将多个字符串合并为⼀个新的字符串。
      1. 语法: 字符或⼦串.join(多字符串组成的序列)
      1. 案例
    • list1 = ['a', 'bb', 'ccc', 'dddd'] print('_'.join(list1))# a_bb_ccc_dddd t1 = ('a', 'bb', 'ccc', 'dddd') print('...'.join(t1))# a...bb...ccc...dddd
  • capitalize():将字符串第⼀个字符转换成⼤写。
  • mystr = "hello world and USA and UK and Python" print(mystr.capitalize()) # Hello world and usa and uk and python
    • 注意:capitalize()函数转换后,只字符串第⼀个字符⼤写,其他的字符全都小写。
  • title():将字符串每个单词⾸字⺟转换成大写
  • mystr = "hello world and USA and UK and Python" print(mystr.title()) # Hello World And Usa And Uk And Python
  • lower():将字符串中⼤写转⼩写。
  • mystr = "hello world and USA and UK and Python" print(mystr.lower()) # hello world and usa and uk and python
  • upper():将字符串中⼩写转⼤写
  • mystr = "hello world and USA and UK and Python" print(mystr.upper()) # HELLO WORLD AND USA AND UK AND PYTHON
  • lstrip():删除字符串左侧空⽩字符。
  • mystr = " hello world and USA and UK and Python" print(mystr.lstrip()) # hello world and USA and UK and Python
    • # 删除左侧指定字符串: 字符串序列.lstrip(字符串) mystr = "hello world and USA and UK and Python" print(mystr.lstrip("he")) # llo world and USA and UK and Python
  • rstrip():删除字符串右侧空白字符。
  • mystr = "hello world and USA and UK and Python " print(mystr.rstrip()) # llo world and USA and UK and Python
    • # 删除右侧指定字符串: 字符串序列.rstrip(字符串) mystr = "hello world and USA and UK and Python" print(mystr.rstrip("on")) # hello world and USA and UK and Pyth
  • strip():删除字符串两侧空⽩字符。
  • mystr = " hello world and USA and UK and Python " print(mystr.strip()) # hello world and USA and UK and Python
  • ljust():返回⼀个原字符串左对⻬,并使⽤指定字符(默认空格)填充至对应⻓度的新字符串
      1. 语法: 字符串序列.ljust(长度, 填充字符)
  • mystr = "hello" print(mystr.ljust(10, '1')) # hello11111
  • rjust():返回⼀个原字符串右对⻬,并使用指定字符(默认空格)填充⾄对应⻓度的新字符串,语法和ljust()相同。
  • mystr = "hello" print(mystr.rjust(10, '1')) # 11111hello
  • center():返回⼀个原字符串居中对⻬,并使⽤指定字符(默认空格)填充至对应⻓度的新字符串,语法和ljust()相同
  • mystr = "hello" print(mystr.center(10, '1')) # 11hello111

判断

所谓判断即是判断真假,返回的结果是布尔型数据类型:True 或 False
  • startswith():检查字符串是否是以指定⼦串开头,是则返回 True,否则返回 False。如果设置开始和结束位置下标,则在指定范围内检查。
      1. 语法: 字符串序列.startswith(⼦串, 开始位置下标, 结束位置下标)
      1. 案例
    • mystr = "hello world and USA and UK and Python " print(mystr.startswith("hello", 5, 20)) # False print(mystr.startswith("hello", 0, 5)) # True
  • endswith():检查字符串是否是以指定⼦串结尾,是则返回True,否则返回False。如果设置开始和结束位置下标,则在指定范围内检查。
      1. 语法: 字符串序列.endswith(⼦串, 开始位置下标, 结束位置下标)
      1. 案例
    • mystr = "hello world and USA and UK and Python" print(mystr.endswith("Python", 5, 20)) # False print(mystr.endswith("Python")) # True
  • isalpha():如果字符串⾄少有一个字符并且所有字符都是字⺟则返回 True, 否则返回 False
  • mystr1 = 'hello' mystr2 = 'hello123' print(mystr1.isalpha()) # True print(mystr2.isalpha()) # False
  • isdigit():如果字符串只包含数字则返回 True 否则返回 False
  • mystr1 = 'hello123' mystr2 = '123' print(mystr1.isdigit()) # False print(mystr2.isdigit()) # True
  • isalnum():如果字符串⾄少有一个字符并且所有字符都是字⺟或数字则返回 True,否则返回 False。
  • mystr1 = 'hello123' mystr2 = '123-' print(mystr1.isalnum()) # True print(mystr2.isalnum()) # False
  • isspace():如果字符串中只包含空⽩,则返回 True,否则返回 False。
  • mystr1 = 'hello123' mystr2 = ' ' print(mystr1.isspace()) # False print(mystr2.isspace()) # True

列表

列表可以⼀次性存储多个数据,且可以为不同数据类型。
格式: [数据1, 数据2, 数据3, 数据4......]

查找

  • 按下标查询
name_list = ['Tom', 'Lily', 'Rose'] print(name_list[0]) # Tom print(name_list[1]) # Lily print(name_list[2]) # Rose
  • 查询函数
      1. index():返回指定数据所在位置的下标 。如果不存在则报错
  • 语法: 列表序列.index(数据, 开始位置下标, 结束位置下标)
    • name_list = ['Tom', 'Lily', 'Rose'] print(name_list.index('Lily', 0, 2)) # 1
      1. count():统计指定数据在当前列表中出现的次数。
      name_list = ['Tom', 'Lily', 'Rose'] print(name_list.count('Lily')) # 1
      1. len():访问列表长度,即列表中数据的个数。
      name_list = ['Tom', 'Lily', 'Rose'] print(len(name_list)) # 3
  • 判断是否存在
      1. in:判断指定数据在某个列表序列,如果在返回True,否则返回False
    • name_list = ['Tom', 'Lily', 'Rose'] # 结果:True print('Lily' in name_list) # 结果:False print('Lilys' in name_list)
      1. not in:判断指定数据不在某个列表序列,如果不在返回True,否则返回False
    • name_list = ['Tom', 'Lily', 'Rose'] # 结果:False print('Lily' not in name_list) # 结果:True print('Lilys' not in name_list)

增加

作⽤:增加指定数据到列表中。
  • append():列表结尾追加数据。
      1. 语法: 列表序列.append(数据)
    • name_list = ['Tom', 'Lily', 'Rose'] name_list.append('xiaoming') # 结果:['Tom', 'Lily', 'Rose', 'xiaoming'] print(name_list)
      • 列表追加数据的时候,直接在原列表⾥⾯追加了指定数据,即修改了原列表,故列表为可变类型数据。
        如果append()追加的数据是⼀个序列,则追加整个序列到列表
        name_list = ['Tom', 'Lily', 'Rose'] name_list.append(['xiaoming', 'xiaohong']) # 结果:['Tom', 'Lily', 'Rose', ['xiaoming', 'xiaohong']] print(name_list)
  • extend():列表结尾追加数据,如果数据是⼀个序列,则将这个序列的数据逐⼀添加到列表
      1. 语法 :列表序列.extend(数据)
    • 单个数据
      • name_list = ['Tom', 'Lily', 'Rose'] name_list.extend('xiaoming') # 结果:['Tom', 'Lily', 'Rose', 'x', 'i', 'a', 'o', 'm', 'i', 'n', 'g'] print(name_list)
        序列数据
        name_list = ['Tom', 'Lily', 'Rose'] name_list.extend(['xiaoming', 'xiaohong']) # 结果:['Tom', 'Lily', 'Rose', 'xiaoming', 'xiaohong'] print(name_list)
  • insert():指定位置新增数据。
      1. 语法: 列表序列.insert(位置下标, 数据)
    • name_list = ['Tom', 'Lily', 'Rose'] name_list.insert(1, 'xiaoming') # 结果:['Tom', 'xiaoming', 'Lily', 'Rose'] print(name_list)

删除

  • del
      1. 语法: del ⽬标
    • 删除指定数据
      • name_list = ['Tom', 'Lily', 'Rose'] # 结果:报错提示:name 'name_list' is not defined del name_list[0] print(name_list)
        删除列表
        name_list = ['Tom', 'Lily', 'Rose'] # 结果:报错提示:name 'name_list' is not defined del name_list print(name_list)
  • pop():删除指定下标的数据(默认为最后⼀个),并返回该数据。
      1. 语法: 列表序列.pop(下标)
    • name_list = ['Tom', 'Lily', 'Rose'] del_name = name_list.pop(1) # 结果:Lily print(del_name) # 结果:['Tom', 'Rose'] print(name_list) name_list.pop() # ['Tom'] print(name_list)
  • remove():移除列表中某个数据的第⼀个匹配项。
      1. 语法
    • name_list = ['Tom', 'Lily', 'Rose'] name_list.remove('Rose') # 结果:['Tom', 'Lily'] print(name_list)
  • clear():清空列表
  • name_list = ['Tom', 'Lily', 'Rose'] name_list.clear() print(name_list) # 结果: []

修改

  • 修改指定下标数据
  • name_list = ['Tom', 'Lily', 'Rose'] name_list[0] = 'aaa' # 结果:['aaa', 'Lily', 'Rose'] print(name_list)
  • 逆置:reverse()
  • name_list = ['Tom', 'Lily', 'Rose'] name_list.reverse() print(name_list)# 结果:['Rose', 'Lily', 'Tom']
  • 排序:sort()
      1. 语法: 列表序列.sort( key=None, reverse=False),排序的是列表里的具体数值
    • 数字
      • num_list = [1, 5, 2, 3, 6, 8] num_list.sort() # 结果:[1, 2, 3, 5, 6, 8] print(num_list)
        字符串 按首字母排序
        name_list = ['Tom', 'Lily', 'Rose'] name_list.sort(key=None, reverse=True) # 结果:['Rose', 'Lily', 'Tom'] print(name_list)
        注意:reverse表示排序规则,reverse = True 降序, reverse = False 升序(默认)

    复制

    函数:copy()
    name_list = ['Tom', 'Lily', 'Rose'] name_li2 = name_list.copy() # 结果:['Tom', 'Lily', 'Rose'] print(name_li2)

    列表的循环遍历

    while
    name_list = ['Tom', 'Lily', 'Rose'] i = 0 while i < len(name_list): print(name_list[i]) i += 1
    for
    name_list = ['Tom', 'Lily', 'Rose'] for i in name_list: print(i)

    列表嵌套

    所谓列表嵌套指的就是⼀个列表⾥⾯包含了其他的⼦列表。 应⽤场景:要存储班级⼀、二、三个班级学⽣姓名,且每个班级的学⽣姓名在⼀个列表。

    元组

    ⼀个元组可以存储多个数据,元组内的数据是不能修改的。

    定义

    元组特点:定义元组使⽤小括号,且逗号隔开各个数据,数据可以是不同的数据类型。
    # 多个数据元组 t1 = (10, 20, 30) # 单个数据元组 t2 = (10,)
    如果定义的元组只有⼀个数据,那么这个数据后⾯也添加逗号,否则数据类型为唯⼀的这个数据的数据类型
    t2 = (10,) print(type(t2)) # tuple t3 = (20) print(type(t3)) # int t4 = ('hello') print(type(t4)) # str

    查询

    • 按下标查找数据
    • tuple1 = ('aa', 'bb', 'cc', 'bb') print(tuple1.index('aa')) # 0
    • index():查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index ⽅法相同
    • tuple1 = ('aa', 'bb', 'cc', 'bb') print(tuple1.index('aa')) # 0
    • count():统计某个数据在当前元组出现的次数。
    • tuple1 = ('aa', 'bb', 'cc', 'bb') print(tuple1.count('bb')) # 2
    • len():统计元组中数据的个数。
    • tuple1 = ('aa', 'bb', 'cc', 'bb') print(len(tuple1)) # 4
    注意:元组内的直接数据如果修改则立即报错
    tuple1 = ('aa', 'bb', 'cc', 'bb') tuple1[0] = 'aaa'
    但是如果元组⾥⾯有列表,修改列表⾥⾯的数据则是⽀持的,故自觉很重要。
    tuple2 = (10, 20, ['aa', 'bb', 'cc'], 50, 30) print(tuple2[2]) # 访问到列列表 # 结果:(10, 20, ['aaaaa', 'bb', 'cc'], 50, 30) tuple2[2][0] = 'aaaaa' print(tuple2)

    集合

    创建集合

    创建集合使⽤ {} 或 set() , 但是如果要创建空集合只能使⽤set() ,因为 {} 用来创建空字典
    s1 = {10, 20, 30, 40, 50} print(s1) s2 = {10, 30, 20, 10, 30, 40, 30, 50} print(s2) s3 = set('abcdefg') print(s3) s4 = set() print(type(s4)) # set s5 = {} print(type(s5)) # dict
    1. 集合可以去掉重复数据;
    1. 集合数据是⽆序的,故不⽀持下标

    增加

    • add()
    • s1 = {10, 20} s1.add(100) s1.add(10) print(s1) # {100, 10, 20}
      • 因为集合有去重功能,所以,当向集合内追加的数据是当前集合已有数据的话,则不进⾏任何操作。
    • update(), 追加的数据是序列
    • s1 = {10, 20} # s1.update(100) # 报错 s1.update([100, 200]) s1.update('abc') print(s1)

    删除

    • remove(),删除集合中的指定数据,如果数据不存在则报错。
    • s1 = {10, 20} s1.remove(10) print(s1) s1.remove(10) # 报错 print(s1)
    • discard(),删除集合中的指定数据,如果数据不存在也不会报错。
    • s1 = {10, 20} s1.discard(10) print(s1) s1.discard(10) print(s1)
    • pop(),随机删除集合中的某个数据,并返回这个数据。
    • s1 = {10, 20, 30, 40, 50} del_num = s1.pop() print(del_num) print(s1)
      • 查找数据

    • in:判断数据在集合序列
    • not in:判断数据不在集合序列
    s1 = {10, 20, 30, 40, 50} print(10 in s1) # True print(10 not in s1) # False

    字典

    字典里⾯的数据是以键值对形式出现,字典数据和数据顺序没有关系,即字典不支持下标, 后期⽆论数据如何变化,只需要按照对应的键的名字查找数据即可

    创建字典

    语法
    1. 符号为大括号
    1. 数据为键值对形式出现
    1. 各个键值对之间用逗号隔开
    # 有数据字典 dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} # 空字典 dict2 = {} dict3 = dict()
    注意:⼀般称冒号前⾯的为键(key),简称k;冒号后面的为值(value),简称v。

    写法:字典序列[key] = 值
    如果key存在则修改这个key对应的值;如果key不存在则新增此键值对。
    dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} dict1['name'] = 'Rose' # 结果:{'name': 'Rose', 'age': 20, 'gender': '男'} print(dict1) dict1['id'] = 110 # {'name': 'Rose', 'age': 20, 'gender': '男', 'id': 110} print(dict1)
    字典为可变类型。

    • del() / del:删除字典或删除字典中指定键值对
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} del dict1['gender'] # 结果:{'name': 'Tom', 'age': 20} print(dict1)
    • clear():清空字典
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} dict1.clear() print(dict1) # {}

    查询

    • key值查找
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} print(dict1['name']) # Tom print(dict1['id']) # 报错
      • 如果当前查找的key存在,则返回对应的值;否则报错。
    • 字典序列.get(key, 默认值)
    • 注意:如果当前查找的key不存在则返回第⼆个参数(默认值),如果省略第⼆个参数,则返回 None。
      • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} print(dict1.get('name')) # Tom print(dict1.get('id', 110)) # 110 print(dict1.get('id')) # None
    • keys()
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} print(dict1.keys()) # dict_keys(['name', 'age', 'gender'])
    • values()
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} print(dict1.values()) # dict_values(['Tom', 20, '男'])
    • items()
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} print(dict1.items()) # dict_items([('name', 'Tom'), ('age', 20), ('gender', '男')])

    遍历

    • 遍历字典的key
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} for key in dict1.keys(): print(key)
    • 遍历字典的value
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} for value in dict1.values(): print(value)
    • 遍历字典的元素
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} for item in dict1.items(): print(item)
    • 遍历键值对
    • dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'} for key, value in dict1.items(): print(f'{key} = {value}')

    公共操作

    运算符

    +
    # 1. 字符串 str1 = 'aa' str2 = 'bb' str3 = str1 + str2 print(str3) # aabb # 2. 列列表 list1 = [1, 2] list2 = [10, 20] list3 = list1 + list2 print(list3) # [1, 2, 10, 20] # 3. 元组 t1 = (1, 2) t2 = (10, 20) t3 = t1 + t2 print(t3) # (10, 20, 100, 200)
    # 1. 字符串串 print('-' * 10) # ---------# 2. 列列表 list1 = ['hello'] print(list1 * 4) # ['hello', 'hello', 'hello', 'hello'] # 3. 元组 t1 = ('world',) print(t1 * 4) # ('world', 'world', 'world', 'world')
    in或not in
    # 1. 字符串串 print('a' in 'abcd') # True print('a' not in 'abcd') # False # 2. 列列表 list1 = ['a', 'b', 'c', 'd'] print('a' in list1) # True print('a' not in list1) # False # 3. 元组 t1 = ('a', 'b', 'c', 'd') print('aa' in t1) # False print('aa' not in t1) # True

    公共方法

    • len()
    • # 1. 字符串 str1 = 'abcdefg' print(len(str1)) # 7 # 2. 列表 list1 = [10, 20, 30, 40] print(len(list1)) # 4 # 3. 元组 t1 = (10, 20, 30, 40, 50) print(len(t1)) # 5 # 4. 集合 s1 = {10, 20, 30} print(len(s1)) # 3 # 5. 字典 dict1 = {'name': 'Rose', 'age': 18} print(len(dict1)) # 2
    • del
    • # 1. 字符串 str1 = 'abcdefg' del str1 # print(str1) NameError: name 'str1' is not defined # 2. 列列表 list1 = [10, 20, 30, 40] del (list1[0]) print(list1) # [20, 30, 40]
    • max()
    • # 1. 字符串 str1 = 'abcdefg' print(max(str1)) # g # 2. 列表 list1 = [10, 20, 30, 40] print(max(list1)) # 40
    • min()
    • # 1. 字符串 str1 = 'abcdefg' print(min(str1)) # a # 2. 列表 list1 = [10, 20, 30, 40] print(min(list1)) # 10
    • range()
    • # 1 2 3 4 5 6 7 8 9 for i in range(1, 10, 1): print(i) # 1 3 5 7 9 for i in range(1, 10, 2): print(i) # 0 1 2 3 4 5 6 7 8 9 for i in range(10): print(i)
      • range()⽣成的序列不包含end数字。
    • enumerate()
    • 语法:enumerate(可遍历对象, start=0),注意:start参数⽤来设置遍历数据的下标的起始值,默认为0。
      • list1 = ['a', 'b', 'c', 'd', 'e'] for i in enumerate(list1): print(i) for index, char in enumerate(list1, start=1): print(f'下标是{index}, 对应的字符是{char}') #(0, 'a') #(1, 'b') #(2, 'c') #(3, 'd') #(4, 'e') #下标是1, 对应的字符是a #下标是2, 对应的字符是b #下标是3, 对应的字符是c #下标是4, 对应的字符是d #下标是5, 对应的字符是e

    容器类型转换

    • tuple() 转换成元组
    • list1 = [10, 20, 30, 40, 50, 20] s1 = {100, 200, 300, 400, 500} print(tuple(list1)) # (10, 20, 30, 40, 50, 20) print(tuple(s1)) # (100, 200, 300, 400, 500)
    • list() 转换成列表
    • t1 = ('a', 'b', 'c', 'd', 'e') s1 = {100, 200, 300, 400, 500} print(list(t1)) # ['a', 'b', 'c', 'd', 'e'] print(list(s1)) # [100, 200, 300, 400, 500]
    • set() 转换成集合
    • list1 = [10, 20, 30, 40, 50, 20] t1 = ('a', 'b', 'c', 'd', 'e') print(set(list1)) # {40, 10, 50, 20, 30} print(set(t1)) # {'c', 'a', 'b', 'e', 'd'}
      • 集合可以快速完成列表去重

    推导式

    列表推导式

    需求:创建⼀个0-10的列表。
    • while循环实现
    • # 1. 准备⼀个空列表 list1 = [] # 2. 书写循环,依次追加数字到空列表list1中 i = 0 while i < 10: list1.append(i) i += 1 print(list1)
    • for循环实现
    • list1 = [] for i in range(10): list1.append(i) print(list1)
      • 列表推导式实现
        list1 = [i for i in range(10)] print(list1)

    带if的列表推导式

    需求:创建0-10的偶数列表
    • 方法一:range()步长实现
    list1 = [i for i in range(0, 10, 2)] print(list1)
    • 方法⼆:if实现
    • list1 = [i for i in range(10) if i % 2 == 0] print(list1)

    多个for循环创建列表推导式

    创建如下列表
    [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] list1 = [(i, j) for i in range(1, 3) for j in range(3)] print(list1)

    字典推导式

    字典推导式作用:快速合并列表为字典或提取字典中⽬标数据。
    1. 创建⼀个字典:字典key是1-5数字,value是这个数字的2次⽅
    dict1 = {i: i**2 for i in range(1, 5)} print(dict1) # {1: 1, 2: 4, 3: 9, 4: 16}
    2. 将两个列表合并为⼀个字典
    list1 = ['name', 'age', 'gender'] list2 = ['Tom', 20, 'man'] dict1 = {list1[i]: list2[i] for i in range(len(list1))} print(dict1)
    1. 提取字典中⽬标数据
    • counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'acer': 99} # 需求:提取上述电脑数量量⼤大于等于200的字典数据 count1 = {key: value for key, value in counts.items() if value >= 200} print(count1) # {'MBP': 268, 'DELL': 201}

    集合推导式

    创建⼀个集合,数据为下方列表的2次方。
    list1 = [1, 1, 2] list1 = [1, 1, 2] set1 = {i ** 2 for i in list1} print(set1) # {1, 4}
    注意:集合有数据去重功能。

    函数

    函数就是将⼀段具有独⽴功能的代码块 整合到⼀个整体并命名,在需要的位置调⽤这个名称即可完成对应的需求。 函数在开发过程中,可以更高效的实现代码重⽤。

    函数基本使用

    • 定义
    def 函数名(参数): 代码1 代码2 ......
    • 调用
    不需要获取返回值
    函数名(参数)
    需要获取返回值
    # 使⽤变量保存函数返回值 变量名 = 函数名(参数)
    • 说明⽂档
    定义函数的说明⽂档
    def 函数名(参数): """ 说明⽂文档的位置 """ 代码 ......
    查看函数的说明⽂档: help(函数名)
    • 嵌套调⽤
    所谓函数嵌套调⽤指的是⼀个函数里⾯又调⽤了另外⼀个函数。
    def testB(): print('---- testB start----') print('这⾥里是testB函数执行的代码...(省略)...') print('---- testB end----') def testA(): print('---- testA start----') testB() print('---- testA end----') testA() # ---- testA start---- # ---- testB start---- # 这⾥里是testB函数执行的代码...(省略)... # ---- testB end---- # ---- testA end----
    如果函数A中,调⽤了另外⼀个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次函数A执⾏的位置。
    • 变量作⽤域
    变量作用域指的是变量生效的范围,主要分为两类:局部变量和全局变量。
    局部变量: 所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
    def testA(): a = 100 print(a) testA() # 100 print(a) # 报错:name 'a' is not defined
    局部变量的作⽤:在函数体内部,临时保存数据,即当函数调⽤完成后,则销毁局部变量。
    全局变量: 所谓全局变量,指的是在函数体内、外都能生效的变量。
    a = 100 def testA(): print(a) def testB(): # global 关键字声明a是全局变量 global a a = 200 print(a) testA() # 100 testB() # 200 print(f'全局变量量a = {a}') # 全局变量a = 200
    在函数体内可通过global关键字声明全局变量
    • 返回多个值的处理
    def return_num(): return 1 return 2 result = return_num() print(result) # 1
    只执⾏了第⼀个return,原因是因为return可以退出当前函数,导致return下方的代码不执⾏
    def return_num(): return 1, 2 result = return_num() print(result) # (1, 2)
    1. return a, b写法,返回多个数据的时候,默认是元组类型。
    1. return后⾯可以连接列表、元组或字典,以返回多个值。
    • 函数的参数
    位置参数: 调⽤函数时根据函数定义的参数位置来传递参数
    def user_info(name, age, gender): print(f'您的名字是{name}, 年年龄是{age}, 性别是{gender}') user_info('TOM', 20, '男')
    注意:传递和定义参数的顺序及个数必须⼀致。
    关键字参数
    def user_info(name, age, gender): print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}') user_info('Rose', age=20, gender='⼥') user_info('⼩明', gender='男', age=16)
    函数调⽤,通过“键=值”形式加以指定。可以让函数更加清晰、容易使⽤,同时也清除了参数的顺序需求。
    注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
    缺省参数
    缺省参数也叫默认参数,⽤于定义函数,为参数提供默认值,调⽤函数时可不传该默认参数的值(注 意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
    def user_info(name, age, gender='男'): print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}') user_info('TOM', 20) user_info('Rose', 18, '⼥')
    函数调⽤时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值。
    不定⻓参数
    不定⻓参数也叫可变参数。⽤于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进⾏参数传递,会显得非常⽅便。
    1. 包裹位置传递
    • def user_info(*args): print(args) # <class 'tuple'> print(type(args)) # ('TOM',) user_info('TOM') # ('TOM', 18) user_info('TOM', 18)
      • 传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple), args是元组类型,这就是包裹位置传递。
    1. 包裹关键字传递
    • def user_info(**kwargs): print(kwargs) # {'name': 'TOM', 'age': 18, 'id': 110} user_info(name='TOM', age=18, id=110)
    • 拆包和交换变量值
        1. 拆包
      • 拆包:元组
        • def return_num(): return 100, 200 num1, num2 = return_num() print(num1) # 100 print(num2) # 200
          拆包:字典
          dict1 = {'name': 'TOM', 'age': 18} a, b = dict1 # 对字典进⾏拆包,取出来的是字典的key print(a) # name print(b) # age print(dict1[a]) # TOM print(dict1[b]) # 18
        1. 交换变量值
      • 借助第三变量存储数据。
        • a = 10 b = 20 # 1. 定义中间变量量 c = 0 # 2. 将a的数据存储到c c = a # 3. 将b的数据20赋值到a,此时a = 20 a = b # 4. 将之前c的数据10赋值到b,此时b = 10 b = c print(a) # 20 print(b) # 10
          方法二
          a, b = 1, 2 a, b = b, a print(a) # 2 print(b) # 1
    • 引⽤
    在python中,值是靠引⽤来传递来的。我们可以⽤ id()来判断两个变量是否为同⼀个值的引用。 我们可以将id值理解为那块内存的地址标
    识。
    # 1. int类型 a = 1 b = a print(b) # 1 print(id(a)) # 140711653204816 print(id(b)) # 140711653204816 a = 2 print(b) # 1,说明int类型为不不可变类型 print(id(a)) # 140711653204848,此时得到是的数据2的内存地址 print(id(b)) # 140711653204816 # 2. 列列表 aa = [10, 20] bb = aa print(id(aa)) # 2466244616840 print(id(bb)) # 2466244616840 aa.append(30) print(bb) # [10, 20, 30], 列列表为可变类型 print(id(aa)) # 2466244616840 print(id(bb)) # 2466244616840 def test1(a): print(a) print(id(a)) a += a print(a) print(id(a)) # int:计算前后id值不不同 b = 100 test1(b) # 列列表:计算前后id值相同 c = [11, 22] test1(c)
    所谓可变类型与不可变类型是指:
    数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变. 可变类型 :
    • 列表
    • 字典
    • 集合
    不可变类型:
    • 整型
    • 浮点型
    • 字符串
    • 元组

    函数进阶

    • 递归
    • # 3 + 2 + 1 def sum_numbers(num): # 1.如果是1,直接返回1 -- 出⼝口 if num == 1: return 1 # 2.如果不是1,重复执行累加: result = num + sum_numbers(num - 1) # 3.返回累加结果 return result sum_result = sum_numbers(3) # 输出结果为6 print(sum_result)
      • notion image
        image-20201211135449400
    • lambda 表达式
    • 如果⼀个函数有⼀个返回值,并且只有⼀句代码,可以使用 lambda简化。
      • 语法: lambda 参数列表 : 表达式
        lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适⽤。 lambda函数能接收任何数量的参数但只能返回一个表达式的值
        案例1
        # 函数 def fn1(): return 200 print(fn1) # <function fn1 at 0x00000204F23DC268> print(fn1()) # lambda表达式 fn2 = lambda: 100 print(fn2) # <function <lambda> at 0x00000204F28E4730> print(fn2()) # 直接打印lambda表达式,输出的是此lambda的内存地址
        案例2 计算a + b
        print((lambda a, b: a + b)(1, 2)) # 3
        lambda的参数形式
        无参数
        print((lambda: 100)()) # 100
        ⼀个参数
        print((lambda a: a)('hello world')) # hello world
        可变参数:*args
        print((lambda *args: args)(10, 20, 30)) # (10, 20, 30)
        可变参数:**kwargs
        print((lambda **kwargs: kwargs)(name='python', age=20)) # {'name': 'python', 'age': 20}
        带判断的lambda
        print((lambda a, b: a if a > b else b)(400, 500)) # 500
        列表数据按字典key的值排序
        students = [{'name': 'TOM', 'age': 20}, {'name': 'ROSE', 'age': 19}, {'name': 'Jack', 'age': 22}] # 按name值升序排列 students.sort(key=lambda x: x['name']) print(students) # 按name值降序排列 students.sort(key=lambda x: x['name'], reverse=True) print(students) # 按age值升序排列 students.sort(key=lambda x: x['age']) print(students)
    • ⾼阶函数
    把函数作为参数传入,这样的函数称为⾼阶函数,⾼阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式
    案例 1 求两数绝对值和
    def sum_num(a, b, f): return f(a) + f(b) result = sum_num(-1, 2, abs) print(result) # 3
    函数式编程大量使⽤函数,减少了代码的重复,因此程序⽐比较短,开发速度较快。
    内置⾼阶函数
    • map()
    • map(func, lst),将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的列表(Python2)/ 迭代器(Python3)返回。
      • list1 = [1, 2, 3, 4, 5] def func(x): return x ** 2 result = map(func, list1) print(result) # <map object at 0x0000013769653198> print(list(result)) # [1, 4, 9, 16, 25]
    • reduce()
    • reduce(func(x,y),lst),其中func必须有两个参数。每次func计算的结果继续和序列的下⼀个元素做累积计算。
      • 计算 list1 序列中各个数字的累加和
        import functools list1 = [1, 2, 3, 4, 5] def func(a, b): return a + b result = functools.reduce(func, list1) print(result) # 15
    • filter()
    • filter(func, lst)函数⽤于过滤序列, 过滤掉不符合条件的元素, 返回⼀个 filter 对象,。如果要转换为列表, 可以使⽤ list() 来转换。
      • list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def func(x): return x % 2 == 0 result = filter(func, list1) print(result) # <filter object at 0x0000017AF9DC3198> print(list(result)) # [2, 4, 6, 8, 10]

    文件操作

    ⽂件操作的作用就是把⼀些内容(数据)存储存放起来,可以让程序下一次执行的时候直接使用,⽽而不必重新制作一份

    文件基本操作

    1. 打开文件
    1. 读写等操作
    1. 关闭⽂件
    在python,使⽤open函数,可以打开⼀个已经存在的⽂文件,或者创建一个新⽂件,语法如下:
    open(name, mode)
    name:是要打开的⽬标文件名的字符串(可以包含文件所在的具体路径)。不包含路径,默认项目根目录
    mode:设置打开⽂件的模式(访问模式):只读、写⼊、追加等
    notion image
    image-20201211145024836
    创建文件对象: f = open(name, mode)
    写: 对象.write(内容)
    读:
    1. ⽂件对象.read(num): num表示要从⽂件中读取的数据的⻓度(单位是字节),如果没有传入num,那么就表示读取⽂件中所有的数据。
    1. readlines()
    • readlines可以按照行的⽅式把整个⽂件中的内容进⾏⼀次性读取,并且返回的是⼀个列表,其中每⼀行的数据为一个元素。
      • f = open('test.txt') content = f.readlines() # ['hello world\n', '#2 aa\n', '@ 113'] print(content) # 关闭⽂文件 f.close()
    1. readline()
    • readline()⼀次读取⼀行内容。
      • f = open('test.txt') content = f.readline() print(f'第⼀行:{content}') content = f.readline() print(f'第⼆行:{content}') # 关闭⽂文件 f.close()
    移动文件指针:⽂件对象.seek(偏移量, 起始位置)
    案例1
    # 1. 打开⽂文件 f = open('test.txt', 'w') # 2.⽂文件写⼊入 f.write('hello world') # 3. 关闭⽂文件 f.close() # w 和 a 模式:如果⽂件不存在则创建该文件;如果文件存在, w 模式先清空再写入, a 模式直接末尾追加。r 模式:如果文件不存在则报错
    起始位置: 0:⽂件开头 1:当前位置 2:⽂件结尾,python3种 起始位置不为0的时候,偏移量必须为0
    关闭: ⽂件对象.close()
    f = open('test.txt') content = f.readline() print(f'第⼀行:{content}') f.seek(f.seek(0, 2) - 4, 0) # 读文件倒数4个字符 content = f.readline() print(f'第⼆行:{content}') # 关闭⽂文件 f.close()
    案例 : 备份文件
    old_name = input('请输⼊您要备份的文件名:') # 2.1 提取⽂文件后缀点的下标 index = old_name.rfind('.') print(index) # 后缀中.的下标 print(old_name[:index]) # 源文件名(无后缀) # 2.2 组织新文件名 旧文件名 + [备份] + 后缀 new_name = old_name[:index] + '[备份]' + old_name[index:] # 打印新⽂文件名(带后缀) print(new_name) # 3.1 打开⽂文件 old_f = open(old_name, 'rb') new_f = open(new_name, 'wb') # 3.2 将源⽂文件数据写⼊入备份⽂文件 while True: con = old_f.read(1024) if len(con) == 0: break new_f.write(con) # 3.3 关闭⽂文件 old_f.close() new_f.close()

    ⽂件和⽂件夹的操作

    在Python中文件和⽂件夹的操作要借助os模块里⾯的相关功能
    1. 导⼊os模块 import os
    1. 使⽤os 模块相关功能 os.函数名()
        • ⽂件重命名os.rename(⽬标⽂件名, 新⽂件名)
        • 删除文件 os.remove(⽬标⽂件名)
        • 创建⽂件夹 os.mkdir(⽂件夹名字)
        • 删除⽂件夹 os.rmdir(文件夹名字)
        • 获取当前目录 os.getcwd()
        • 改变默认⽬录 os.chdir(⽬录)
        • 获取⽬录列表 os.listdir(⽬录)
    import os # 设置重命名标识:如果为1则添加指定字符,flag取值为2则删除指定字符 flag = 1 # 获取指定⽬目录 dir_name = '../' # 获取指定⽬目录的⽂文件列列表 file_list = os.listdir(dir_name) print(file_list) # 遍历⽂件列表内的文件 for name in file_list: # 添加指定字符 if flag == 1: new_name = 'Python-' + name # 删除指定字符 elif flag == 2: num = len('Python-') new_name = name[num:] # 打印新文件名,测试程序正确性 print(new_name) # 重命名 os.rename(dir_name + name, dir_name + new_name)

    面向对象

    类和对象

    类是对一系列具有相同特征和行为的事物的统称,是⼀个抽象的概念,不是真实存在的事物
    • 特征即是属性
    • 行为即是方法
    对象是类创建出来的真实存在的事物

    面向对象实现方法

    定义类
    class 类名(): 代码 ......
    类名要满⾜标识符命名规则,同时遵循大驼峰命名习惯。
    经典类 不由任意内置类型派生出的类,称之为经典类
    创建对象
    对象名 = 类名()
    class Washer(): def wash(self): print('我会洗⾐服') # 创建对象 haier1 = Washer() # <__main__.Washer object at 0x0000018B7B224240> print(haier1) # haier对象调用实例方法 haier1.wash()
    创建对象的过程也叫实例化对象。
    self
    self指的是调⽤该函数的对象。打印对象和self得到的结果是一致的,都是当前对象的内存中存储地址。
    添加和获取对象属性
    添加语法 : 对象名.属性名 = 值
    类外获取语法: 对象名.属性名 , 类内获取语法 self.属性名

    魔法方法

    在Python中, xx() 的函数叫做魔法⽅法,指的是具有特殊功能的函数
    __init__ 方法的作⽤:初始化对象,赋予属性默认值
    __init__ 方法,在创建⼀个对象时默认被调用,不需要⼿动调⽤ __init__(self) 中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。
    class Washer: def __init__(self, width, height): self.width = width self.height = height def print_info(self): print(f'洗⾐机的宽度是{self.width}') print(f'洗⾐机的高度是{self.height}') haier1 = Washer(20, 10) haier1.print_info() haier2 = Washer(30, 40) haier2.print_info()
    __str__方法,类似Java的toString,当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__方法,那么就会打印从在这个方法中 return 的数据
    class Washer: def __init__(self, width, height): self.width = width self.height = height def print_info(self): print(f'洗⾐机的宽度是{self.width}') print(f'洗⾐机的高度是{self.height}') def __str__(self): return '洗⾐机的宽度是' + str(self.width) + '洗⾐机的高度是' + str(self.height) haier1 = Washer(20, 10) print(haier1) haier2 = Washer(30, 40) print(haier2)
    __del__ 当删除对象时,python解释器也会默认调⽤ del() 方法。
    class Washer: def __init__(self, width, height): self.width = width self.height = height def print_info(self): print(f'洗⾐机的宽度是{self.width}') print(f'洗⾐机的高度是{self.height}') def __str__(self): return '洗⾐机的宽度是' + str(self.width) + '洗⾐机的高度是' + str(self.height) def __del__(self): print(f'{self}对象已经被删除') haier1 = Washer(20, 10) haier2 = Washer(30, 40)
    __mro__方法:获取这个类的调用顺序

    继承

    Python⾯向对象的继承指的是多个类之间的所属关系,即⼦类默认继承⽗类的所有属性和⽅法在Python中,所有类默认继承object类,object类是顶级类或基类;其他⼦类叫做派⽣类。
    # ⽗类A class A(object): def __init__(self): self.num = 1 def info_print(self): print(self.num) # ⼦类B class B(A): pass result = B() result.info_print() # 1
    多继承
    所谓多继承意思就是一个类同时继承了多个父类。当⼀个类有多个父类的时候,默认使⽤第一个⽗类的同名属性和方法。
    class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦子配⽅方]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') # 创建学校类 class School(object): def __init__(self): self.kongfu = '[私塾煎饼果⼦配方]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class Prentice(School, Master): pass daqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake()
    ⼦类重写⽗类同名⽅法和属性
    ⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法
    class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[私塾煎饼果子配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' def make_cake(self): # 如果是先调⽤了父类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调用属性前,先调⽤自⼰子类的初始化 # self.__init__() print(f'运⽤{self.kongfu}制作煎饼果子') # 调⽤父类⽅法,但是为保证调用到的也是⽗类的属性,必须在调⽤方法前调⽤父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) daqiu = Prentice() daqiu.make_cake() daqiu.make_master_cake() daqiu.make_school_cake() daqiu.make_cake() # 运⽤[独创煎饼果⼦配⽅]制作煎饼果子 # 运⽤[古法煎饼果⼦配⽅]制作煎饼果子 # 运⽤[私塾煎饼果子配⽅]制作煎饼果子 # 运⽤[私塾煎饼果子配⽅]制作煎饼果子 调用父类的属性和⽅法,⽗类属性会覆盖⼦类属性
    多层继承
    class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[私塾煎饼果子配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' def make_cake(self): # 如果是先调⽤了父类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调用属性前,先调⽤自⼰子类的初始化 self.__init__() print(f'运⽤{self.kongfu}制作煎饼果子') # 调⽤父类⽅法,但是为保证调用到的也是⽗类的属性,必须在调⽤方法前调⽤父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) class TuSun(Prentice): pass xiaoqiu = TuSun() xiaoqiu.make_cake() xiaoqiu.make_school_cake() xiaoqiu.make_master_cake()
    super 关键字
    使⽤super() 可以自查找⽗类。调⽤顺序遵循 __mro__ 类属性的顺序。⽐较适合单继承使用。
    class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[私塾煎饼果子配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' def make_cake(self): # 如果是先调⽤了父类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调用属性前,先调⽤自⼰子类的初始化 self.__init__() print(f'运⽤{self.kongfu}制作煎饼果子') # 调⽤父类⽅法,但是为保证调用到的也是⽗类的属性,必须在调⽤方法前调⽤父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) def make_old_cake(self): super(Prentice, self).__init__() super(Prentice, self).make_cake() # super().__init__() # super().make_cake() class TuSun(Prentice): pass xiaoqiu = TuSun() xiaoqiu.make_old_cake()

    私有权限

    1. 定义私有属性和方法
    • 在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。
      • 设置私有权限的方法:在属性名和⽅法名前面 加上两个下划线
        class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[私塾煎饼果子配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' self.__money = 2000000 def make_cake(self): # 如果是先调⽤了父类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调用属性前,先调⽤自⼰子类的初始化 self.__init__() print(f'运⽤{self.kongfu}制作煎饼果子') # 调⽤父类⽅法,但是为保证调用到的也是⽗类的属性,必须在调⽤方法前调⽤父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) def make_old_cake(self): super(Prentice, self).__init__() super(Prentice, self).make_cake() # 定义私有⽅方法 def __info_print(self): print(self.kongfu) print(self.__money) class TuSun(Prentice): pass daqiu = Prentice() # 对象不能访问私有属性和私有方法 # print(daqiu.__money) # daqiu.__info_print() xiaoqiu = TuSun() # ⼦类⽆法继承⽗类的私有属性和私有⽅法 # print(xiaoqiu.__money) # ⽆无法访问实例例属性__money # xiaoqiu.__info_print()
        注意:
      • ⼦类⽆法继承⽗类的私有属性和私有方法
      • 对象不能直接访问私有属性和私有方法
      • 私有属性和私有⽅法只能在类⾥面访问和修改。
    1. 获取和修改私有属性值
    在Python中,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx ⽤来修改私有属性值
    class Master(object): def __init__(self): self.kongfu = '[古法煎饼果⼦配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class School(object): def __init__(self): self.kongfu = '[私塾煎饼果子配⽅]' def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果子') class Prentice(School, Master): def __init__(self): self.kongfu = '[独创煎饼果⼦配⽅]' self.__money = 2000000 def make_cake(self): # 如果是先调⽤了父类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调用属性前,先调⽤自⼰子类的初始化 self.__init__() print(f'运⽤{self.kongfu}制作煎饼果子') # 调⽤父类⽅法,但是为保证调用到的也是⽗类的属性,必须在调⽤方法前调⽤父类的初始化 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) def make_old_cake(self): super(Prentice, self).__init__() super(Prentice, self).make_cake() # 定义私有⽅方法 def __info_print(self): print(self.kongfu) print(self.__money) # 获取私有属性 def get_money(self): return self.__money # 修改私有属性 def set_money(self): self.__money = 500 class TuSun(Prentice): pass xiaoqiu = TuSun() print(xiaoqiu.get_money()) xiaoqiu.set_money() print(xiaoqiu.get_money())

    ⾯向对象三大特性

    • 封装
    • 将属性和⽅法书写到类的里⾯的操作即为封装
      • 封装可以为属性和⽅法添加私有权限
    • 继承
    • ⼦类默认继承父类的所有属性和⽅法
      • ⼦类可以重写父类属性和方法
    • 多态
    • 传⼊不同的对象,产⽣不同的结果
    class Dog(object): def work(self): print('指哪打哪...') class ArmyDog(Dog): # 继承Dog类 def work(self): # ⼦类重写⽗类同名方法 print('追击敌⼈...') class DrugDog(Dog): def work(self): print('追查毒品...') class Person(object): def work_with_dog(self, dog): # 传⼊不同的对象,执⾏不同的代码,即不同的work函数 dog.work() ad = ArmyDog() dd = DrugDog() daqiu = Person() daqiu.work_with_dog(ad) daqiu.work_with_dog(dd) # 追击敌⼈... # 追查毒品...

    类属性和实例属性

    类属性就是类对象所拥有的属性,它被该类的所有实例对象所共有
    类属性可以使⽤类对象 或 实例对象访问
    class Dog(object): tooth = 10 wangcai = Dog() xiaohei = Dog() print(Dog.tooth) # 10 print(wangcai.tooth) # 10 print(xiaohei.tooth) # 10
    类的实例记录的某项数据始终保持⼀致时,则定义类属性。
    实例属性 要求每个对象为其单独开辟一份内存空间来记录数据,而类属性为全类所共有 ,
    仅占⽤一份内存,更加节省内存空间
    修改类属性
    类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性。
    class Dog(object): tooth = 10 Dog.tooth = 12 wangcai = Dog() xiaohei = Dog() print(Dog.tooth) # 10 print(wangcai.tooth) # 10 print(xiaohei.tooth) # 10 wangcai.tooth = 20 print(Dog.tooth) # 12 print(wangcai.tooth) # 20 print(xiaohei.tooth) # 12
    实例属性不能通过类访问

    类方法和静态方法

    1. 类方法
        • 第⼀个形参是类对象的⽅法
        • 需要用装饰器 @classmethod 来标识其为类⽅法,对于类方法,第⼀个参数必须是类对象,⼀般以 cls 作为第⼀个参数
    • 使用场景
      • 当方法中需要使用类对象 (如访问私有类属性等)时,定义类方法
      • 类⽅法⼀般和类属性配合使用
      • class Dog(object): __tooth = 10 @classmethod def get_tooth(cls): return cls.__tooth wangcai = Dog() result = wangcai.get_tooth() print(result) # 10
    1. 静态方法
        • 需要⽤装饰器 @staticmethod 来标识其为静态方法,静态⽅法既不需要传递类对象也不需要传递实例对象 (形参没有self/cls)
        • 静态⽅方法 也能够通过 实例例对象 和 类对象 去访问
      • 使用场景
        • 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅法、创建实例等)时,定义静态方法
        • 取消不需要的参数传递,有利于减少不必要的内存占⽤和性能消耗
        • class Dog(object): @staticmethod def info_print(): print('这是⼀个狗类,⽤于创建狗实例....') wangcai = Dog() # 静态⽅法既可以使⽤对象访问⼜可以使⽤类访问 wangcai.info_print() Dog.info_print()

      异常

      语法
      try: 可能发⽣错误的代码 except: 如果出现异常执行的代码
      案例
      try: f = open('test.txt', 'r') except: f = open('test.txt', 'w')
      捕获指定异常
      try: 可能发⽣错误的代码 except 异常类型: 如果捕获到该异常类型执行的代码 try: print(num) except NameError: print('有错误')
      1. 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则⽆法捕获异常。
      1. 一般try下方只放⼀行尝试执行的代码。
      捕获多个指定异常
      当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的⽅式进行书写
      try: print(1 / 0) except (NameError, ZeroDivisionError): print('有错误')
      捕获异常描述信息
      try: print(num) except (NameError, ZeroDivisionError) as result: print(result) # name 'num' is not defined
      捕获所有异常
      Exception是所有程序异常类的⽗类。
      try: print(num) except Exception as result: print(result) # name 'num' is not defined
      异常的else
      else表示的是如果没有异常要执行的代码。
      num = 1 try: print(num) except Exception as result: print(result) else: print('我是else,是没有异常的时候执⾏的代码')
      异常的finally
      finally表示的是⽆论是否异常都要执行的代码,例如关闭文件。
      try: f = open('test.txt', 'r') except: f = open('test.txt', 'w') finally f.close()
      异常传递
      • 当函数/方法执行出现异常,会将异常传递给函数/方法的调用方
      • 如果传递到主程序,仍然没有异常处理,程序才会被终止
      def demo1(): return int(input("输入整数:")) def demo2(): return demo1() # 利用异常的传递性,在主程序捕获异常 try: print(demo2()) except Exception as result: print("未知错误 %s" % result) # demo1()发生异常 --> 传递给demo2() --> 传递给主程序 print()函数 --> 主程序如果未捕获,程序终止
      自定义异常
      在Python中,抛出自定义异常的语法为 raise 异常类对象
      # 自定义异常类,继承Exception class ShortInputError(Exception): def __init__(self, length, min_len): self.length = length self.min_len = min_len # 设置抛出异常的描述信息 def __str__(self): return f'你输⼊的⻓度是{self.length}, 不能少于{self.min_len}个字符' def main(): try: con = input('请输⼊密码:') if len(con) < 3: raise ShortInputError(len(con), 3) except Exception as result: print(result) else: print('密码已经输⼊入完成') main()

      模块和包

      1. 模块
      • Python 模块(Module),是⼀个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。 模块能定义函数,类和变量,模块⾥也能包含可执行的代码
        • 导⼊模块
        • 方式:
            1. import 模块名
          • 语法
            • # 1. 导⼊模块 import 模块名 import 模块名1, 模块名2... # 2. 调⽤功能 模块名.功能名()
              import math print(math.sqrt(9)) # 3.0
            1. from 模块名 import 功能名
          • 语法
            • from 模块名 import 功能1, 功能2, 功能3...
              from math import sqrt print(sqrt(9))
            1. from 模块名 import *
          • 语法
            • from 模块名 import *
              from math import * print(sqrt(9))
            1. import 模块名 as 别名
            1. from 模块名 import 功能名 as 别名
          • as定义别名
            • # 模块定义别名 import 模块名 as 别名 # 功能定义别名 from 模块名 import 功能 as 别名
              # 模块别名 import time as tt tt.sleep(2) print('hello') # 功能别名 from time import sleep as sl sl(2) print('hello')
      **制作模块** 在Python中,每个Python⽂件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则 **测试模块** 在实际开发中,当一个开发⼈员编写完⼀个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py⽂文件中添加⼀些测试信息.,例如,在 my_module1.py ⽂件中添加测试代码 ```python def testA(a, b): print(a + b) testA(1, 1) ``` 此时,⽆论是当前文件,还是其他已经导入了该模块的⽂件,在运行的时候都会自动执行 testA函数的调用。解决办法如下: ```python def testA(a, b): print(a + b) # 只在当前⽂件中调⽤该函数,其他导入的⽂件内不符合该条件,则不执⾏testA函数调用 if __name__ == '__main__': testA(1, 1) ``` 调⽤模块 ```python import myModule1 myModule1.testA(1, 1) ``` 如果使⽤` from .. import ..`或`from .. import *`导⼊多个模块的时候,且模块内有同名功能。当调用这个同名功能的时候,调⽤到的是后⾯导入的模块的功能 ```python # 模块1代码 def my_test(a, b): print(a + b)
      # 模块2代码 def my_test(a, b): print(a - b)
      # 导⼊入模块和调⽤用功能代码 from my_module1 import my_test from my_module2 import my_test # my_test函数是模块2中的函数 my_test(1, 1) ```模块定位顺序 当导⼊一个模块,Python解析器对模块位置的搜索顺序是:
      1. 当前⽬录 2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。 3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径⼀般为`/usr/local/lib/python/` 模块搜索路径存储在system模块的sys.path变量中。变量⾥包含当前目录,PYTHONPATH和由安装过程决定的默认目录 自⼰的⽂件名不要和已有模块名重复,否则导致模块功能⽆法使用 `__all__` 如果⼀个模块文件中有 __all__ 变量,当使⽤` from xxx import * `导⼊时,只能导入这个列表中的元素。 myModule1.py ```python __all__ = ['testA']
      def testA(): print('testA')
      def testB(): print('testB') python from myModule1 import * testA() testB() # testA # Traceback (most recent call last): # File "E:/study/PyProjects/pachong/myPyTest1.py", line 5, in # testB() # NameError: name 'testB' is not defined ```
      • 包将有联系的模块组织在一起,即放到同⼀个文件夹下,并且在这个文件夹创建⼀个名字为 init.py ⽂件,那么这个⽂件夹就称之为包
      制作包
      notion image
      image-20201216092928719
      新建包后,包内部会⾃动创建 init.py 文件,这个文件控制着包的导入⾏为
      1. 新建包 mypackage
      1. 新建包内模块: my_module1 和 my_module2
      1. 模块内代码如下
      # my_module1 print(1) def info_print1(): print('my_module1') # my_module2 print(2) def info_print2(): print('my_module2')
      导入包
      方法一import 包名.模块名 包名.模块名.目标
      import mypackage.my_module1 mypackage.my_module1.info_print1()
      ⽅法⼆
      必须在 init.py ⽂件中添加 all = [] ,控制允许导入的模块列表。
      from 包名 import * 模块名.⽬目标 from mypackage import * my_module1.info_print1() # 不添加 __all__ = [] # NameError: name 'my_module1' is not defined

      python 应用

      网络爬虫

      request库安装pip3 install requests
      Beautiful Soup4 安装 :pip3 install bs4pip3 install lxml