变量

  • 定义变量的语法

变量名 = 值

  • 标识符

    • 由数字、字母、下划线组成

    • 不能数字开头

    • 不能使用内置关键字

    • 严格区分大小写

  • 数据类型

    • 整型: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. 接收用户输入的文件名

  2. 规划备份文件名

  3. 备份文件写入数据

# 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模块里面的相关功能,具体步骤如下:

  1. 导入os模块

  2. 使用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解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  3. 如果都找不到,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__ = [] :允许导入的模块或功能列表