变量
定义变量的语法
变量名 = 值
标识符
由数字、字母、下划线组成
不能数字开头
不能使用内置关键字
严格区分大小写
数据类型
整型:int
浮点型:float
字符串:str
布尔型:bool
元组:tuple
集合:set
字典:dict
输出
格式化输出 (格式化符号)
%s:格式化输出字符串
%d:格式化输出整数
%f:格式化输出浮点数
f-字符串
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}岁了')
转义字符
\n:换行
\t:制表符
print结束符
print('内容', end="")
输入
输入的语法
input("提示信息")
password = input('请输入您的密码:')
print(f'您输入的密码是{password}')
# <class 'str'>
print(type(password))
转换数据类型
# 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 |
逻辑运算符
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔"与":如果 x 为 False,x and y 返回 False,否则它返回 y 的值。 | True and False, 返回 False。 |
or | x or y | 布尔"或":如果 x 是 True,它返回 True,否则它返回 y 的值。 | False or True, 返回 True。 |
not | not x | 布尔"非":如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not True 返回 False, not False 返回 True |
流程控制
条件语句
if语句
if True:
print('条件成立执行的代码1')
print('条件成立执行的代码2')
# 下方的代码没有缩进到if语句块,所以和if条件无关
print('我是无论条件是否成立都要执行的代码')
if...else...语句
age = int(input('请输入您的年龄:'))
if age >= 18:
print(f'您的年龄是{age},已经成年,可以上网')
else:
print(f'您的年龄是{age},未成年,请自行回家写作业')
print('系统关闭')
多重判断
age = int(input('请输入您的年龄:'))
if age < 18:
print(f'您的年龄是{age},童工一枚')
elif (age >= 18) and (age <= 60):
print(f'您的年龄是{age},合法工龄')
elif age > 60:
print(f'您的年龄是{age},可以退休')
if嵌套
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('没钱,不能上车,追着公交车跑')
三目运算符
值1 if 条件 else 值2
a = 1
b = 2
c = a if a > b else b
print(c)
循环语句
while语句
#计算1-100偶数累加和
# 方法一:条件判断和2取余数为0则累加计算
i = 1
result = 0
while i <= 100:
if i % 2 == 0:
result += i
i += 1
# 输出2550
print(result)
# 方法二:计数器控制增量为2
i = 0
result = 0
while i <= 100:
result += i
i += 2
# 输出2550
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循环嵌套
# 重复打印5行星星
# j表示行号
j = 0
while j <= 4:
# 一行星星的打印
i = 0
# i表示每行里面星星的个数,这个数字要和行号相等所以i要和j联动
while i <= j:
print('*', end='')
i += 1
print()
j += 1
#九九乘法表
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
else
while...else
循环可以和else配合使用,else下⽅缩进的代码指的是当循环正常结束之后要执行的代码
while 条件:
条件成立重复执行的代码
else:
循环正常结束之后要执行的代码
所谓else指的是循环正常结束之后要执行的代码,即如果是break终止循环的情况,else下方缩进的代码将不执行
continue是退出当前一次循环,继续下一次循环,所以该循环在continue控制下是可以正常结束的,当循环结束后,则执行了else缩进的代码
for...else
for 临时变量量 in 序列列:
重复执⾏行行的代码
...
else:
循环正常结束之后要执⾏行行的代码
数据序列
字符串
字符串输入输出
下标
计算机为数据序列列中每个元素分配的从0开始的编号
切片
切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作
序列[开始位置下标:结束位置下标:步长]
常用操作方法
查找
所谓字符串查找方法即是查找子串在字符串中的位置或出现的次数
find():检测某个子串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,否则则返回-1。
字符串序列.find(子串, 开始位置下标, 结束位置下标)
开始和结束位置下标可以省略,表示在整个字符串序列中查找开始和结束位置下标可以省略,表示在整个字符串序列中查找
index():检测某个子串是否包含在这个字符串中,如果在返回这个子串开始的位置下标,否则则报异常。
字符串序列.index(子串, 开始位置下标, 结束位置下标)
rfind(): 和find()功能相同,但查找方向为右侧开始。
rindex():和index()功能相同,但查找方向为右侧开始。
count():返回某个⼦串在字符串中出现的次数
字符串串序列列.count(子串, 开始位置下标, 结束位置下标)
修改
所谓修改字符串,指的就是通过函数的形式修改字符串中的数据。
replace():替换
字符串序列.replace(旧子串, 新子串, 替换次数)
注意:替换次数如果查出子串出现次数,则替换次数为该子串出现次数
split():按照指定字符分割字符串
字符串序列.split(分割字符, num)
注意:num表示的是分割字符出现的次数,即将来返回数据个数为num+1个
mystr = "hello world and itcast and itheima and Python"
print(mystr.split('and'))
# 结果:['hello world ', ' itcast ', ' itheima ', ' Python']
print(mystr.split('and', 2))
# 结果:['hello world ', ' itcast ', ' itheima and Python']
print(mystr.split(' '))
# 结果:['hello', 'world', 'and', 'itcast', 'and', 'itheima', 'and', 'Python']
print(mystr.split(' ', 2))
# 结果:['hello', 'world', 'and itcast and itheima and Python']
如果分割字符是原有字符串中的子串,分割后则丢失该子串
join():用一个字符或子串合并字符串,即是将多个字符串合并为一个新的字符串
字符或子串.join(多字符串组成的序列)
list1 = ['chuan', 'zhi', 'bo', 'ke']
t1 = ('aa', 'b', 'cc', 'ddd')
# 结果:chuan_zhi_bo_ke
print('_'.join(list1))
# 结果:aa...b...cc...ddd
print('...'.join(t1))list1 = ['chuan', 'zhi', 'bo', 'ke']
t1 = ('aa', 'b', 'cc', 'ddd')
# 结果:chuan_zhi_bo_ke
print('_'.join(list1))
# 结果:aa...b...cc...ddd
print('...'.join(t1))
capitalize():将字符串第一个字符转换成大写
title():将字符串每个单词首字母转换成大写
lower():将字符串中大写转小写
upper():将字符串中小写转大写
lstrip():删除字符串左侧空白字符
rstrip():删除字符串右侧空白字符
strip():删除字符串两侧空白字符
ljust():返回一个原字符串左对齐,并使用指定字符(默认空格)填充至对应长的新字符串
字符串序列.ljust(长度, 填充字符)
rjust():返回一个原字符串右对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同
center():返回一个原字符串居中对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同
startswith():检查字符串是否是以指定子串开头,是则返回 True,否则返回 False
字符串序列.startswith(子串, 开始位置下标, 结束位置下标)
endswith()::检查字符串是否是以指定子串结尾,是则返回 True,否则返回 False
isalpha():如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False
isdigit():如果字符串只包含数字则返回 True 否则返回 False
isalnum():如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False
isspace():如果字符串中只包含空白,则返回 True,否则返回 False
列表
列表的格式
[数据1, 数据2, 数据3, 数据4......]
列表的常用操作
查找
下标
index():返回指定数据所在位置的下标
count():统计指定数据在当前列表中出现的次数
len():访问列表长度,即列表中数据的个数
in:判断指定数据在某个列表序列,如果在返回True,否则返回False
not in:判断指定数据不在某个列表序列,如果不在返回True,否则返回False
增加
append():列表结尾追加数据
如果append()追加的数据是一个序列,则追加整个序列到列表
name_list = ['Tom', 'Lily', 'Rose']
name_list.append(['xiaoming', 'xiaohong'])
# 结果:['Tom', 'Lily', 'Rose', ['xiaoming', 'xiaohong']]
print(name_list)
extend():列表结尾追加数据,如果数据是一个序列,则将这个序列的数据逐一添加到列表
insert():指定位置新增数据
列表序列.insert(位置下标, 数据)
删除
del
name_list = ['Tom', 'Lily', 'Rose']
# 结果:报错提示:name 'name_list' is not defined
del name_list
print(name_list)
name_list = ['Tom', 'Lily', 'Rose']
del name_list[0]
# 结果:['Lily', 'Rose']
print(name_list)
pop():删除指定下标的数据(默认为最后一个),并返回该数据
列表序列.pop(下标)
remove():移除列表中某个数据的第一个匹配项
列表序列.remove(数据)
clear():清空列表
修改
修改指定下标数据
逆置:reverse()
sort()
列表序列.sort( key=None, reverse=False)
reverse表示排序规则,**reverse = True** 降序, reverse = False 升序(默认)
复制
copy()
列表的循环遍历
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)
列表嵌套
所谓列表嵌套指的就是一个列表里面包含了其他的子列表
# 第一步:按下标查找到李四所在的列表
print(name_list[2])
# 第二步:从李四所在的列表里面,再按下标找到数据李四
print(name_list[2][1])
元组
一个元组可以存储多个数据,元组内的数据是不能修改的
定义元组
元组特点:定义元组使用小括号,且逗号隔开各个数据,数据可以是不同的数据类型
如果定义的元组只有一个数据,那么这个数据后面也好添加逗号,否则数据类型为唯一的这个数据的数据类型
# 多个数据元组
t1 = (10, 20, 30)
# 单个数据元组
t2 = (10,)
元组的常见操作
按下标查找数据
tuple1 = ('aa', 'bb', 'cc', 'bb')
print(tuple1[0]) # aa
index():查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index方法相同
count():统计某个数据在当前元组出现的次数
len():统计元组中数据的个数
但是如果元组里面有列表,修改列表里面的数据则是支持的
字典
字典里面的数据是以键值对形式出现,字典数据和数据顺序没有关系,即字典不支持下标
创建字典
# 有数据字典
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
# 空字典
dict2 = {}
dict3 = dict()
字典常见操作
增
字典序列[key] = 值
删
del() / del:删除字典或删除字典中指定键值对
clear():清空字典
改
字典序列[key] = 值
如果key存在则修改这个key对应的值 ;如果key不存在则新增此键值对
查
key值查找
如果当前查找的key存在,则返回对应的值;否则则报错
get()
字典序列.get(key, 默认值)
如果当前查找的key不存在则返回第二个参数(默认值),如果省略第二个参数,则返回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}')
集合
创建集合
创建集合使用
{}或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
集合常见操作方法
增加数据
add()
update(), 追加的数据是序列
s1 = {10, 20}
# s1.update(100) # 报错
s1.update([100, 200])
s1.update('abc')
print(s1)
删除数据
remove(),删除集合中的指定数据,如果数据不存在则报错
discard(),删除集合中的指定数据,如果数据不存在也不会报错
pop(),随机删除集合中的某个数据,并返回这个数据
查找数据
in:判断数据在集合序列
not in:判断数据不在集合序列
公共操作
运算符
运算符 | 描述 | 支持的容器类型 |
---|---|---|
+ | 合并 | 字符串、列表、元组 |
* | 复制 | 字符串、列表、元组 |
in | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 元素是否不存在 | 字符串、列表、元组、字典 |
# 1. 字符串
print('-' * 10) # ----------
# 2. 列表
list1 = ['hello']
print(list1 * 4) # ['hello', 'hello', 'hello', 'hello']
# 3. 元组
t1 = ('world',)
print(t1 * 4) # ('world', 'world', 'world', 'world')
公共方法
函数 | 描述 |
---|---|
len() | 计算容器中元素个数 |
del 或 del() | 删除 |
max() | 返回容器中元素最大值 |
min() | 返回容器中元素最小值 |
range(start, end, step) | 生成从start到end的数字,步长为 step,供for循环使用 |
enumerate() | 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。 |
enumerate(可遍历对象, 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}')
容器类型转换
tuple():将某个序列转换成元组
list():将某个序列转换成列表
set():将某个序列转换成集合
集合可以快速完成列表去重
推导式
列表推导式
用一个表达式创建一个有规律的列表或控制一个有规律列表
list1 = [i for i in range(10)]
print(list1)
list1 = [i for i in range(0, 10, 2)]
print(list1)
list1 = [i for i in range(10) if i % 2 == 0]
print(list1)
list1 = [(i, j) for i in range(1, 3) for j in range(3)]
print(list1)
#结果:[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
字典推导式
dict1 = {i: i**2 for i in range(1, 5)}
print(dict1) # {1: 1, 2: 4, 3: 9, 4: 16}
#将两个列表合并为一个字典
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man']
dict1 = {list1[i]: list2[i] for i in range(len(list1))}
print(dict1)
#提取字典中目标数据
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]
set1 = {i ** 2 for i in list1}
print(set1) # {1, 4}
函数
函数的作用
函数就是将一段具有独立功能的代码块整合到一个整体并命名,在需要的位置调用这个名称即可完成对应的需求
def 函数名(参数):
代码1
代码2
#调用
函数名(参数)
变量的作用域
变量作用域指的是变量生效的范围,主要分为两类:局部变量和全局变量
#函数体内部修改全局变量
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
函数的参数
位置参数
调用函数时根据函数定义的参数位置来传递参数
关键字参数
函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
缺省参数
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递
#包裹位置参数
def user_info(*args):
print(args)
# ('TOM',)
user_info('TOM')
# ('TOM', 18)
user_info('TOM', 18)
#包裹关键字参数
def user_info(**kwargs):
print(kwargs)
# {'name': 'TOM', 'age': 18, 'id': 110}
user_info(name='TOM', age=18, id=110)
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递
无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程
函数的说明文档
函数嵌套调用
拆包
#拆包:元组
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
引用
靠引用来传递值
我们可以
id()
来判断两个变量是否为同一个值的引用。 我们可以将id值理解为那块内存的地址标识
# 1. int类型
a = 1
b = a
print(b) # 1
print(id(a)) # 140708464157520
print(id(b)) # 140708464157520
a = 2
print(b) # 1,说明int类型为不可变类型
print(id(a)) # 140708464157552,此时得到是的数据2的内存地址
print(id(b)) # 140708464157520
# 2. 列表
aa = [10, 20]
bb = aa
print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432
aa.append(30)
print(bb) # [10, 20, 30], 列表为可变类型
print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432
引用当作实参
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,重复执行累加并返回结果
return num + sum_numbers(num-1)
sum_result = sum_numbers(3)
# 输出结果为6
print(sum_result)
lambda表达式
如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda简化
lambda语法
lambda 参数列表 : 表达式
lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用
lambda表达式能接收任何数量的参数但只能返回一个表达式的值
lambda的参数形式
无参数
fn1 = lambda: 100
print(fn1())
一个参数
fn1 = lambda a: a
print(fn1('hello world'))
默认参数
fn1 = lambda a, b, c=100: a + b + c
print(fn1(10, 20))
可变参数:*args
fn1 = lambda *args: args
print(fn1(10, 20, 30))
可变参数:**kwargs
fn1 = lambda **kwargs: kwargs
print(fn1(name='python', age=20))
lambda的应用
带判断的lambda
fn1 = lambda a, b: a if a > b else b
print(fn1(1000, 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)
高阶函数
把函数作为参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。
abs()
def sum_num(a, b, f):
return f(a) + f(b)
result = sum_num(-1, 2, abs)
print(result) # 3
round():四舍五入
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(func,lst):其中func必须有两个参数。每次func计算的结果继续和序列的下一个元素做累积计算。
import functools
list1 = [1, 2, 3, 4, 5]
def func(a, b):
return a + b
result = functools.reduce(func, list1)
print(result) # 15
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]
文件操作
基本操作
打开文件
open(name, mode)
name:要打开的目标文件名的字符串(可以包含文件所在的具体路径)
mode:设置打开文件的模式(访问模式):只读、写入、追加等
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
文件对象方法
写
文件对象.write('内容')
读
read()
文件对象.read(num)
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
readlines()
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
f = open('test.txt')
content = f.readlines()
# ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
print(content)
# 关闭文件
f.close()s
readline():一次读取一行内容
f = open('test.txt')
content = f.readline()
print(f'第一行:{content}')
content = f.readline()
print(f'第二行:{content}')
# 关闭文件
f.close()
seek():移动文件指针
文件对象.seek(偏移量, 起始位置)
起始位置:
- 0:文件开头
- 1:当前位置
- 2:文件结尾
关闭
文件对象.close()
文件备份
用户输入当前目录下任意文件名,程序完成对该文件的备份功能(备份文件名为xx[备份]后缀,例如:test[备份].txt)。
步骤
接收用户输入的文件名
规划备份文件名
备份文件写入数据
# 1 接收用户输入目标文件名
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')
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模块里面的相关功能,具体步骤如下:
导入os模块
使用os模块相关功能
import os
os.函数名()
文件重命名
os.rename(目标文件名, 新文件名)
删除文件
os.remove(目标文件名)
创建文件夹
os.mkdir(文件夹名字)
删除文件夹
os.rmdir(文件夹名字)
获取当前目录
os.getcwd()
改变默认目录
os.chdir(目录)
获取目录列表
os.listdir(目录)
面向对象
类和对象
类和对象的关系:用类创建一个对象
类
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。
特征即是属性
行为即是方法
对象
对象是类创建出来的真实存在的事物
面向对象实现方法
定义类
class 类名():
代码
......
注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯。
创建对象
对象名 = 类名()
创建对象的过程也叫实例化对象
self
self指的是调用该函数的对象
# 1. 定义类
class Washer():
def wash(self):
print('我会洗衣服')
# <__main__.Washer object at 0x0000024BA2B34240>
print(self)
# 2. 创建对象
haier1 = Washer()
# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)
# haier1对象调用实例方法
haier1.wash()
haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2)
打印对象和self得到的结果是一致的,都是当前对象的内存中存储地址
添加和获取对象属性
类外面添加对象属性
对象名.属性名 = 值
对象名.属性名
类里面获取对象属性
self.属性名
# 定义类
class Washer():
def print_info(self):
# 类里面获取实例属性
print(f'haier1洗衣机的宽度是{self.width}')
print(f'haier1洗衣机的高度是{self.height}')
# 创建对象
haier1 = Washer()
# 添加实例属性
haier1.width = 500
haier1.height = 800
haier1.print_info()
魔法方法
在Python中
__xx__()
的函数叫做魔法方法,指的是具有特殊功能的函数。
__init__()
初始化对象
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(10, 20)
haier1.print_info()
haier2 = Washer(30, 40)
haier2.print_info()
__str__()
当使用print输出对象的时候,默认打印对象的内存地址。如果类定义
__str__
方法,那么就会打印从在这个方法中 return 的数据
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return '这是海尔洗衣机的说明书'
haier1 = Washer(10, 20)
# 这是海尔洗衣机的说明书
print(haier1)
__del__()
删除对象
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __del__(self):
print(f'{self}对象已经被删除')
haier1 = Washer(10, 20)
# <__main__.Washer object at 0x0000026118223278>对象已经被删除
del haier1
继承
Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法
# 父类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
在Python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫做派生类
单继承
# 1. 师父类
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
# 2. 徒弟类
class Prentice(Master):
pass
# 3. 创建对象daqiu
daqiu = Prentice()
# 4. 对象访问实例属性
print(daqiu.kongfu)
# 5. 对象调用实例方法
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):
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):
print(f'运用{self.kongfu}制作煎饼果子')
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
print(Prentice.__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)
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()调用父类方法
class Master(object):
def __init__(self):
self.kongfu = '[古法煎饼果子配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class School(Master):
def __init__(self):
self.kongfu = '[黑马煎饼果子配方]'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
# 方法2.1
# super(School, self).__init__()
# super(School, self).make_cake()
# 方法2.2
super().__init__()
super().make_cake()
class Prentice(School):
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):
# 方法一:代码冗余;父类类名如果变化,这里代码需要频繁修改
# Master.__init__(self)
# Master.make_cake(self)
# School.__init__(self)
# School.make_cake(self)
# 方法二: super()
# 方法2.1 super(当前类名, self).函数()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2 super().函数()
super().__init__()
super().make_cake()
daqiu = Prentice()
daqiu.make_old_cake()
使用super() 可以自动查找父类。调用顺序遵循
__mro__
类属性的顺序。比较适合单继承使用
私有权限
定义私有属性和方法
Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类
设置私有权限的方法:在属性名和方法名 前面 加上两个下划线 __
class 类名():
# 私有属性
__属性名 = 值
# 私有方法
def __函数名(self):
代码
获取和修改私有属性值
一般定义函数
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 get_money(self):
return self.__money
# 修改私有属性
def set_money(self):
self.__money = 500
def __info_print(self):
print(self.kongfu)
print(self.__money)
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
daqiu = Prentice()
xiaoqiu = Tusun()
# 调用get_money函数获取私有属性money的值
print(xiaoqiu.get_money())
# 调用set_money函数修改私有属性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()
# 修改类属性
Dog.tooth = 12
print(Dog.tooth) # 12
print(wangcai.tooth) # 12
print(xiaohei.tooth) # 12
# 不能通过对象修改属性,如果这样操作,实则是创建了一个实例属性
wangcai.tooth = 20
print(Dog.tooth) # 12
print(wangcai.tooth) # 20
print(xiaohei.tooth) # 12
实例属性
class Dog(object):
def __init__(self):
self.age = 5
def info_print(self):
print(self.age)
wangcai = Dog()
print(wangcai.age) # 5
# print(Dog.age) # 报错:实例属性不能通过类访问
wangcai.info_print() # 5
类方法和静态方法
类方法
特点
第⼀个形参是类对象的方法
需要用装饰
@classmethod
来标识其为类方法,对于类方法,第一个参数必须是类对象,一般cls
作为第一个参数。
类方法使用场景
当方法中 需要使用类对象 (如访问私有类属性等)时,定义类方法
类方法一般和类属性配合使用
class Dog(object):
__tooth = 10
@classmethod
def get_tooth(cls):
return cls.__tooth
wangcai = Dog()
result = wangcai.get_tooth()
print(result) # 10
静态方法
特点
需要通过装饰
@staticmethod
来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)静态方法 也能够通过 实例对象 和 类对象 去访问。
静态方法使用场景
- 当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
- 取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗
class Dog(object):
@staticmethod
def info_print():
print('这是一个狗类,用于创建狗实例....')
wangcai = Dog()
# 静态方法既可以使用对象访问又可以使用类访问
wangcai.info_print()
Dog.info_print()
异常
捕获异常
捕获指定异常
try:
可能发生错误的代码
except 异常类型:
如果捕获到该异常类型执行的代码
捕获多个指定异常
捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写
try:
print(1/0)
except (NameError, ZeroDivisionError):
print('有错误')
捕获异常描述信息
try:
print(num)
except (NameError, ZeroDivisionError) as result:
print(result)
异常的else
try:
print(1)
except Exception as result:
print(result)
else:
print('我是else,是没有异常的时候执行的代码')
异常的finally
try:
f = open('test.txt', 'r')
except Exception as result:
f = open('test.txt', 'w')
else:
print('没有异常,真开心')
finally:
f.close()
异常的传递
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
# 如果在读取文件的过程中,产生了异常,那么就会捕获到
# 比如 按下了 ctrl+c
print('意外终止了读取数据')
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")
自定义异常
在Python中,抛出自定义异常的语法
raise 异常类对象
。
class 异常类类名(Exception):
代码
# 设置抛出异常的描述信息
def __str__(self):
return ...
# 2. 抛出异常
raise 异常类名()
# 捕获异常
except Exception...
# 自定义异常类,继承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()
模块和包
模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句
模块能定义函数,类和变量,模块里也能包含可执行的代码。
导入模块
- import 模块名
- from 模块名 import 功能名
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
制作模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则
def testA(a, b):
print(a + b)
# 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行testA函数调用
if __name__ == '__main__':
testA(1, 1)
模块定义顺序
当导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
- 注意
- 自己的文件名不要和已有模块名重复,否则导致模块功能无法使用
使用from 模块名 import 功能
的时候,如果功能名字重复,调用到的是最后定义或导入的功能。
“__all__"
如果一个模块文件中
__all__
变量,当使from xxx import *
导入时,只能导入这个列表中的元素。my_module1模块代码
__all__ = ['testA']
def testA():
print('testA')
def testB():
print('testB')
导入模块的文件代码
from my_module1 import *
testA()
testB()
包
包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字
__init__.py
文件,那么这个文件夹就称之为包
制作包
[New] — [Python Package] — 输入包名 — [OK] — 新建功能模块(有联系的模块)。
注意:新建包后,包内部会自动创
__init__.py
文件,这个文件控制着包的导入行为。
import 包名.模块名
from 包名 import *
- __all__ = []
:允许导入的模块或功能列表