Python 基础入门学习
Python的一些基础语法学习笔记
一.基本语句
注释:
#
单行注释"""
多行注释"""
print (" ")
输出函数基本运算符:
+
-
*
/
//
(取整)%
(取余)**
(幂运算)变量的定义:
变量名 = 值
(每个变量使用前都必须赋值,变量在赋值以后才会被创造,定义时不需要指定变量类型)type( )
查看变量类型函数input( )
变量输入函数 用法举例: a = input(“输入数字:”) 输入的任何内容的数据类型默认为字符型strint(a)
float(b)
类型转换函数,将a转换为int型,将b转换为float型格式化输出:
print("格式化字符串" % 变量1)
print("格式化字符串" % (变量1,变量2...))
(%s - 字符串)
(%d - 带符号十进制整数——%06d表示输出六位数,不足地方用0补全)
(%f - 浮点数——%.02f表示小数点后显示两位)
(%% - 输出%)
f-格式化字符串: print(f’ My name is {name} ‘)
转义字符:
\n
换行\t
制表符 : 1个tab键(4个空格)结束符:python中的 print 默认以
\n
为结束符,即默认换行,但可自己设置,如:print('hello', end="\t")
标识符 由字母、数字、下划线组成,不能以数字开头,不能与关键词重名。标识符区分大小写,命名规则推荐多个单词时全部小写并将每个单词用下划线隔开。
if语句: 在Python开发中,Tab和空格一定不能混用!
1
2
3
4
5
6
7
8
9
10
11if 条件1:
条件1成立时要执行的代码
elif 条件2:
条件2成立时要执行的代码
else:
条件1、2都不成立时执行的代码if语句训练:猜拳游戏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#if-elif-else训练: 猜拳游戏
import random
player = int(input('请出拳 (0-拳头 1-剪刀 2-布):'))
computer = random.randint(0,2)
#平局
if player == computer:
print('平局')
#电脑胜
elif ( ((player == 0) and (computer == 2)) or ((player == 1)and(computer == 0)) or ((player == 2)and(computer == 1)) ):
print('电脑赢了!你个睿智!你连电脑都打不过!')
#玩家胜
else:
print('你赢了!不容易不容易啊!')随机数的实现:
导入
random
模块,使用randint
(随机整数) 功 如:1
2
3import random
num = random.randint(0,2) (num为0、1、2中的随机一个数)
三目运算符:
1
条件成立时的表达式 if 条件 else 条件不成立时的表达式
如:
MaxNum = a if a>b else b
While 循环:
1
2
3while 条件:
条件成立时重复执行的代码注意: 计数的初始值习惯写为0
break 和 continue :
break
为终止循环,即不再循环continue
为退出当前一次循环而直接执行下一次循环,即跳入下一次循环for 循环:
1
2
3for 临时变量 in 序列:
重复执行的代码
while 与 else : 如果循环由 break 停止,则else下的代码不执行,for 与 else 的用法与此类似
1
2
3
4
5
6
7while 条件:
条件成立时重复执行的代码
else:
循环正常结束之后执行的代码
二.基本数据类型
字符串可以用单引号、双引号、三引号括起来,字符串为不可变类型。
python中每个字符串自带下标和索引,可用
str[x]
来精确访问字符串 str 中的某个字符切片: 指对 字符串、列表、元组 进行截取其中一部分的操作
语法: 序列[开始位置下标 : 结束位置下标 : 步长]
其中切片不包含结束位置下标对应的数据 ,即开始位置下标和结束位置下标为 [ ) 的包含形式
下标 和 步长 均可不写或写负数,步长默认为1,若下标开始到结束的方向与步长的方向冲突,则无法选取出数据
字符串的查找: find() 、index() 、count() 、rfind() 、rindex()
find()
: 检测某个子串是否包含在这个字符串中,如果存在则返回这个子串开始位置的下标,否则返回-11
字符串序列.find( 子串 , 开始位置下标 , 结束位置下标 )
开始和结束位置下标可以省略,表示在整个字符串序列中查找
index()
: 与find()函数的用法一样,但如果不存在要查找的子串,则会报错count()
:返回某子串在该字符串中出现的次数,若不存在则返回0rfind()
与rindex()
查找方向为从右侧开始,其功能与 find() 与 index() 相同字符串的替换 :replace() 替换
1
字符串序列.replace ( 旧子串、新子串、替换次数 )
注意: replace函数并不会改变原有字符串的数据,修改后的数据是replace函数的返回值
字符串的分割: split() 分割,返回一个列表,丢失分割字符
1
字符串序列.split(分割字符,分割次数)
注意:split函数也不会改变原有字符串数据,修改后的数据为函数返回值
列表的合并:join() 合并,返回一个字符串,添加连接字符
1
连接字符串.join(多字符串组成的列表)
注意: join() 合并 是 split() 分割 的逆序操作
字符串修改大小写函数:
capitalize()
将字符串第一个字母转换为大写,其余均为小写title()
将字符串中每个单词的首字母转化成大写,其余均为小写lower()
将字符串中的大写全部转换为小写upper()
将字符串中的小写全部转换为大写例:
initial: brotheR aNd me
capitalize: Brother and me
title: Brother And Me
lower: brother and me
upper: BROTHER AND ME字符串删除空白字符函数:
lstrip()
: 删除字符串左侧空白字符rstrip()
: 删除字符串右侧空白字符strip()
: 删除字符串两侧空白字符例:
initial: “ brother and me “
lstrip: “brother and me “
rstrip: “ brother and me”
strip: “brother and me”字符串对齐函数: ljust() 、 rjust() 、center()
返回 一个原字符串 左/右/中 对齐,并用指定字符(默认空格)填充至对应长度的新字符串
1
2
3
4
5字符串序列.ljust( 长度 , 填充字符 )
字符串序列.rjust( 长度 , 填充字符 )
字符串序列.center( 长度 , 填充字符 )例:
initial: brother and me
ljust: brother and me—————-
rjust: —————-brother and me
center: ——–brother and me——–字符串判断开头或结尾函数:
startswith()
: 检查字符串是否以指定子串开头,是则返回True,否则返回False。如果设置开始和结束位置下标,则在指定范围内检查1
字符串序列.startswith(子串,开始位置下标,结束位置下标)
endswith()
: 检查字符串是否以指定子串结尾,用法与 startswith()相同1
字符串序列.endswith(子串,开始位置下标,结束位置下标)
字符串字符类型判断函数:
isalpha()
: 如果字符串非空且只包含字母则返回True , 否则返回Falseisdigit()
: 如果字符串非空且只包含数字则返回True , 否则返回Falseisalnum()
: 如果字符串非空且只包含数字或字母则返回True, 否则返回Falseisspace()
: 如果字符串非空且只包含空格则返回True , 否则返回False列表 : 可以用下标选取指定数据,列表为可变类型。
列表数据查找函数:
index()
: 返回指定数据所在位置的下标,若数据不存在则报错1
列表序列.index(数据, 开始位置下标, 结束位置下标)
count()
: 返回指定数据在该列表出现的次数,若数据不存在则返回01
列表序列.count(数据)
len()
: 返回列表的长度,即列表中数据的个数1
len(列表序列)
判断列表中是否存在指定数据:
in
: 判断指定数据在某个序列的存在,存在返回True,否则返回False1
'指定数据' in 列表序列
not in
: 与 in 的用法相同,返回结果相反列表数据增加函数:
append()
: 列表结尾追加数据,若数据为一个序列,则直接追加整个序列到列表的结尾位置1
列表序列.append(数据)
extend()
: 列表结尾追加数据,若数据为一个序列,则将序列的数据逐一添加到列表,若数据为字符串,则将单独的每个字符逐一添加到列表1
列表序列.extend(数据)
insert()
: 指定位置新增数据,增添方式与 append() 相同1
列表序列.insert(位置下表,数据)
列表数据删除函数:
del 目标(列表名 或 列表指定下标数据)
pop()
: 删除指定下标的数据(默认为最后一个),并返回该数据。1
列表序列.pop(下标)
remove()
: 移除列表中某个数据的第一个匹配项,若匹配失败则报错1
列表序列.remove(数据)
clear()
: 清空列表中的所有数据1
列表序列.clear()
列表数据修改函数:
修改指定下标数据: 列表序列[下标] = 数据
reverse()
: 将列表数据的顺序逆置1
列表序列.reverse()
sort()
: 对列表的数据进行排序1
列表序列.sort( key = None, reverse = False)
注意: reverse = True 降序 reverse = False 升序(默认)
列表数据复制函数:
copy()
: 列表数据复制1
新列表序列 = 原列表序列.copy()
即将原列表的数据复制到新列表中
列表的循环遍历:
while循环方法 :
1
2
3
4
5
6
7i = 0
while i < len(list):
print(list[i])
i += 1for循环方法 :
1
2
3for i in list:
print(i)列表嵌套:指一个列表里包含了其他的子列表。
例:
List = [ ['a' , 'b' , 'c'] , ['1' , '2' , '3'] , ['&' , '$' , '%'] ]
列表综合训练:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#将8位老师随机分配到3个办公室中
import random
teacher = ['a1','a2','a3','a4','a5','a6','a7','a8']
room = [[],[],[]]
for i in teacher:
n = random.randint(0,2)
room[n].append(i)
print(room)
i = 1
for r in room:
print(f'办公室{i}的人数是{len(r)},他们分别为:',end = '\t')
for name in r:
print(name,end = '\t')
print()
i += 1
元组: 一个元组可以存储多个数据(与列表相同),但元组内的数据是不能修改的。
元组名 (数据1 , 数据2 , 数据3)
注意: 如果定义的元组只有一个数据,那么需要添加逗号,凑则数据类型为该数据类型,而不是 元组(tuple) 数据类型,如 tuple = (‘x’ , )
元组的常见操作:
按下标查找数据 : 如tuple1[0] 、 tuple1[1]等
index()
: 查找某个数据,用法与字符串、列表的index相同count()
: 统计某个数据在当前元组出现的次数len()
: 统计元组中的数据个数元组数据的修改:
元组内的直接数据如果修改则立即报错
如果元组里面有列表,可直接修改列表内的数据,如 (‘abc’ , ‘qwe’ , [‘123’ , ‘456’ , ‘789’] , ‘jkl’) 元组就可以修改其中的 ‘123’ , ‘456’ , ‘789’ 数据
字典:字典里的数据是以键值对形式存储的。字典为可变类型。
特点: 符号为大括号,数据为键值对形式出现,各个键值对之间用逗号隔开。
1
dict1 = { '键1' : '值1' , '键2' : '值2' , '键3' : '值3' }
空字典除了可以用空大括号创建,也可以用函数创建: dict2 = dict()
字典常见操作:
增 / 改: 字典序列[‘key’] = 值
注意: 如果key存在则修改该键对应的值,如果key不存在则新增此键值对
删:
del(dict)
删除字典del dict['Key']
删除字典中指定键值对dict.clear()
清空字典查:
按key值写法直接查找: 字典序列[‘键’]
按函数写法查找: get() keys() values() items()
get()
: 获取某个键对应的值1
字典序列.get(key , 默认值)
注意:若当前查找的key不存在则返回默认值,若默认值省略不写则返回None
keys()
: 获取字典中所有的key,并返回可迭代对象1
字典序列.keys()
values()
: 获取字典中所有的values,并返回可迭代对象1
字典序列.values()
items()
: 获取字典中所有的键值对(key 和 values),并返回可迭代对象 ,里面的数据是元组1
字典序列.items()
字典的循环遍历:
遍历字典的Key:
1
2for key in dict1.keys():
print(key)遍历字典的Value:
1
2for value in dict1.values():
print(value)遍历字典的元素:
1
2for item in dict1.items():
print(item)遍历字典的**键值对(拆包)**:
1
2for key, value in dict1.items():
print(f'{key} = {value}')
集合: 创建集合可使用 {} 或 set() ,但是如果要创建空集合只能使用 set() , 因为使用 {} 会创建空字典。
集合数据特点: 集合里面的数据会自动去重,不允许重复;集合里面的数据没有顺序,且不支持下标。集合是可变类型。
集合的创建:
直接创建:
s1 = {10 , 20 , 30 , 40 , 50}
使用set()创建:
s2 = set('brother')
创建空集合:
s3 = set()
集合中数据的常见操作:
增加数据: add() update()
集合.add(数据)
增加单个数据,要增加的数据在原集合中存在的话,不进行任何操作集合.update(数据列表)
在集合中增加数据序列删除数据: remove() discard() pop()
集合.remove(数据)
删除集合中的指定数据,如果数据不存在则会报错集合.discard(数据)
删除集合中的指定数据,如果数据不存在也不会报错集合.pop()
随即删除集合中的某个数据,并返回这个数据查找数据: in 判断数据在集合序列 not in 判断数据不在集合序列
公共操作:运算符、公共方法、容器类型转换
运算符:
+
合并,支持字符串、列表、元组*
复制,支持字符串、列表、元组in
元素是否存在,支持字符串、列表、元组、字典not in
元素是否不存在,支持字符串、列表、元组、字典公共方法:
len()
计算容器中元素个数del()
删除元素max()
返回容器中元素的最大值min()
返回容器中元素的最小值range(start,end,step)
生成从start到end的数字(其中不包含end数字),步长为step,供for循环使用enumerate()
将一个可遍历的数据对象(列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环中1
enumerate(可遍历对象, start=0)
容器类型转换:
tuple(序列)
: 将某个序列转换成元组list(序列)
: 将某个序列转换成列表set(序列)
: 将某个序列转换成集合推导式(生成式): 列表推导式、字典推导式、集合推导式
作用: 化简代码
列表推导式:用一个表达式创建一个有规律的列表或控制一个有规律列表。
创建0-10的列表:
1
list = [i for i in range(10)]
创建0-10的偶数列表:
1
list = [i for i in range(10) if i % 2 == 0]
多个for循环列表:
1
list = [(i , j) for i in range(3) for j in range(3)]
字典推导式:快速合并列表为字典或提取字典中目标数据
赋值体验:
1
dict = {i:i*2 for i in range(1,5)}
将两个列表合并为字典:
1
2
3
4
5list1 = ['name' , 'age' , 'gender']
list2 = ['Tom' , 20 , 'man']
dict = { list1[i] : list2[i] for i in range(len(list1)) }提取字典中目标数据:
1
2
3counts = {'a' : 150 , 'b' : 200 , 'c' : 250}
count = {key : value for key , value in counts.items() if value >= 200}集合推导式:
1
2list = [1,1,2]
set = {i * 2 for i in list}
三.函数
函数:
def 函数名(参数):
“”” 说明文档内容 “””
代码1
代码2
…….
注意:参数可有可无,必须先定义后使用
函数中return之后的代码并不会执行
help(函数名) 查看函数解释说明的信息
函数(二):
局部变量:只在函数体内部生效的变量
全局变量:指在函数体内、外都能生效的变量
在函数体内部修改全局变量:在函数体内部用 global 声明变量为全局变量后修改
函数有多个返回值时: return 后面可以直接书写 元组、列表、字典,返回多个值
位置参数:调用函数时根据函数定义的参数位置来传递参数,传递和定义参数的顺序及个数必须一致
关键字参数:函数调用时,通过“键=值”的形式加以指定传参,关键字参数之间不存在先后顺序
缺省参数:也叫默认参数,用于在定义函数时为参数提供默认值,调用函数时可以不传入有默认值的参数。在定义和调用函数时,位置参数必须在缺省参数之前
不定长参数:也叫可变参数,用于不确定调用时会传递多少个参数的场景,可用 包裹位置参数 或 包裹关键字参数 来进行参数传递
包裹位置传递(元组):
1
2
3
4def 函数名( *args ):
print( args )
函数名( 'abc' , 123 )包裹关键字传递(字典):
1
2
3
4def 函数名( **kwargs):
print( kwargs )
函数名( a = 'abc' , b = 123)包裹位置传递和包裹关键字传递都是一个组包的过程,即收集零散数据并组成一个元组或字典
返回值拆包:
元组: return 10, 20 num1, num2 = 函数 即得到num1 = 10 , num2 = 20
字典: 对字典拆包,得到的是字典的key
交换变量值:
方法一:借助第三变量存储数据
方法二: a, b = b, a
引用: 在python中,值是靠引用来传递的
可以用 id() 来判断两个变量是否为同一个值的引用。可以将id理解为那块内存的地址标识。
可变类型与不可变类型:
可变类型:列表(list)、字典(dict)、集合(set)
不可变类型:整型、浮点型、字符串、元组
函数加强应用—学员管理系统:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122#定义功能界面函数
def print_info():
"""函数功能界面"""
print('---select---')
print('1.add')
print('2.delete')
print('3.modify')
print('4.query')
print('5.show all')
print('6.exit')
print('----end----')
#定义列表等待存储学员信息
info = []
#添加学员信息函数
def add_info():
"""学员添加函数"""
new_name = input('input name:')
new_id = input('input id:')
new_tel = input('input telephone:')
global info
for i in info:
if new_name == i['name']:
print('name exists!')
#return 退出当前函数,不执行下面添加信息的代码
return
info_dict = {}
info_dict['name'] = new_name
info_dict['id'] = new_id
info_dict['tel'] = new_tel
info.append(info_dict)
print('add successful!')
#删除学员信息
def del_info():
"""学员删除函数"""
del_name = input('input name:')
global info
for i in info:
if del_name == i['name']:
info.remove(i)
print('delete successful!')
break
else:
print('name does not exist!')
#修改学员信息
def modify_info():
"""学员信息修改函数"""
modify_name = input('input name:')
global info
for i in info:
if modify_name == i['name']:
i['tel'] = input('input new telephone:')
print('modify successful!')
break
else:
print('name does not exist!')
#查询学员信息
def search_info():
"""查询信息函数"""
search_name = input('input name:')
global info
for i in info:
if search_name == i['name']:
print('---Message---')
print(f"The name is {i['name']}, The id is {i['id']}, The telephone is {i['tel']}。")
break
else:
print('name does not exist!')
#展示所有学员信息函数
def showall_info():
"""展示信息函数"""
print('name\tid\ttelephone')
global info
for i in info:
print(f"{i['name']}\t{i['id']}\t{i['tel']}")
while True:
#1.显示功能界面
print_info()
#2.用户输入功能序号
user_num = int(input('your choice:'))
#3.按照用户输入的功能序号,执行不同的功能(函数)
if user_num == 1:
add_info()
elif user_num == 2:
del_info()
elif user_num == 3:
modify_info()
elif user_num == 4:
search_info()
elif user_num == 5:
showall_info()
elif user_num == 6:
exit_flag = input('are you sure? Y/N')
if exit_flag == 'Y':
break
else:
print('Error!')递归:
特点: 函数内部自己调用自己、必须有出口。
1
2
3
4
5
6
7#递归函数求1~n的累加和
def num(n):
#出口
if n == 1:
return 1
#函数内部自己调用自己
return n+num(n-1)若没有出口,则报错提示超出最大递归深度(996)。
lambda表达式(匿名函数)
:应用场景: 化简代码。如果一个函数只有一个返回值,并且只有一句代码,可以使用lambda简化。
1
lambda 参数列表: 表达式
lambda表达式的参数列表可有可无,函数的参数在lambda表达式中完全适用。
lambda表达式能够接收任何数量的参数但只能返回一个表达式的值。
1
2
3
4#计算 a+b 的lambda实现
fn = lambda a,b: a+b
print(fn(1,2))
#输出结果: 3lambda的参数形式:无参、有参、缺省参数(默认)、可变参数*args、可变参数**kwargs。
1
2
3
4
5
6
7
8
9
10
11
12
13
14#无参
fn1 = lambda : 100
#有参
fn2 = lambda a: a
#缺省参数
fn3 = lambda a,b,c=100: a+b+c
#可变参数 *args(元组)
fn4 = lambda *args: args
#可变参数 *kwargs(字典)
fn5 = lambda **kwargs: kwargslambda的应用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#1.带判断的lambda
fn1 = lambda a,b: a if a>b else b #两个数比大小
fn2 = lambda n: n+fn2(n-1) if n != 1 else 1 #递归求1~n的累加和
#2.列表数据按字典key的值排序
students = [
{'name':'Tom','age':19},
{'name':'Alice','age':20},
{'name':'Hack','age':18}
]
students.sort(key=lambda n: n['name']) #按照名字首字母升序排序
students.sort(key=lambda n: n['age'], reverse=True) #按照年龄降序排序高阶函数:
把函数作为参数传入,这样的函数称为高阶函数(即复合函数)。
测试用到的小函数:
**abs()**:对数字求绝对值
**round()**:对数字进行四舍五入
1
2
3
4
5
6
7
8def sum(a, b, f):
return f(a)+f(b)
result1 = sum(3.14, -2.8, abs)
result2 = sum(3.14, -2.8, round)
#lambda表达式改写
sum = lambda a,b,f: f(a)+f(b)Python内置高阶函数: map()、reduce()、filter()。
map(func, list)
:将传入的函数变量func作用到列表变量list中的每个元素中,并将结果组成新的列表(python2)/迭代器(python3)返回。
1 | #计算list1序列中各个数字的三次方 |
reduce(func, list)
:functools模块中的一个高阶函数,其中func必须有两个参数。每次func结算的结果继续和序列的下一个元素做累积计算。
1 | #计算list2序列中各个数字的累加和 |
filter(func, list)
:用于过滤序列,过滤掉不符合条件的元素,并返回一个filter对象。可用 list() 转换为列表。
1 | #过滤list3序列中所有的偶数,只留下奇数 |
四.文件操作
文件操作:
作用:把一些内容(数据)存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力。
文件操作步骤:打开文件、读写等操作、关闭文件。
open()
:打开一个已经存在的文件,或创建一个新文件。1
2
3
4
5f = open(name, mode)
#name: 是要打开的目标文件名的字符串(可以包含文件所在的具体路径)
#mode: 设置打开文件的模式(访问模式):只读、写入、追加等
#此时f为name文件的文件对象,可通过f执行之后的读写等操作主访问模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式(访问模式未指定时,即为只读模式)。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 (b) 以二进制形式读取 (+) 可读可写 访问模式r+、w+、a+的区别:
r+
:没有该文件则报错,文件指针在开头故能读取数据w+
:没有该文件会新建,文件指针在开头并会用新内容覆盖原有内容,故无法读取文件内原有的数据a+
:没有该文件会新建,文件指针在结尾故不能读取数据写入内容:write()
1
文件对象.write('内容')
读取内容:read()、readlines()、readline()。
1
2
3
4
5
6
7
8文件对象.read(num)
#num 表示要从文件中读取的数据的长度。不写则默认读取所有数据。其中换行符'\n'会占一位
文件对象.readnlines()
#按照行的方式把整个文件的内容进行一次性读取,并返回一个列表,其中每一行数据为一个元素
文件对象.readline()
#一次读取一行内容、重复调用readline()则依次读取文件中每一行的内容移动文件指针:seek()
1
2
3文件对象.seek(偏移量,起始位置)
#起始位置参数: 0开头 1当前 2结尾应用:
1
2
3
4
5
6
7#使用 a 访问模式打开文件,通过改变文件指针位置来读取数据
f = open('test.txt','a')
f.seek(0,0) #此时可简写为 f.seek(0)
con = f.read()
f.close()文件备份案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#用户输入当前目录下任意文件名,程序完成对该文件的备份功功能(备份文件名为 xx[备份].后缀)
#1.接收用户输入的文件名
old_name = input('input yoru backup file name:')
#2.规划备份文件名
index = old_name.rfind('.') #文件名中'.'的位置
if index > 0: #判断文件名,防止出现'.txt'类的无效文件名
postfix = old_name[index:]
new_name = old_name[:index] + '[备份]' + postfix #利用字符串的切片重新规划备份文件名
#3.备份文件写入数据
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)
new_f.close()
old_f.close()文件和文件夹的操作:
模块:使用 os 模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import os
#1.文件操作
#文件重命名,也可以重命名文件夹
os.rename(目标文件名或路径, 新文件名)
#文件删除,也可以删除文件夹
os.remove(目标文件名)
#2.文件夹操作
#创建文件夹
os.mkdir(文件夹名字)
#删除文件夹
os.rmdir(文件夹名字)
#3.目录操作
#获取当前目录
os.getcwd()
#改变当前默认目录
os.chdir(目录文件夹)
#获取目录列表
os.listdir(目录文件夹)文件和文件夹操作应用案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#批量修改文件名,既可添加指定字符串,又能删除指定字符串
import os
#构造条件数据
flag = input('输入操作类型(1为添加,2为删除):')
#构造指定字符串
str = input('请输入指定字符串:')
#找到所有文件
file_list = os.listdir()
#添加或删除指定字符串
for i in file_list:
if flag == '1':
new_name = str + i
elif flag == '2':
num = len(str)
new_name = i[num:]
else:
print('操作模式输入错误!')
break
#重命名
os.rename(i, new_name)
五.面向对象
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。对象是由类创建出来的真实存在的事物。
1
2
3
4
5
6
7
8
9#创建类
class 类名(): #类名要满足标识符命名规则,同时遵循大驼峰命名习惯
代码
......
def 函数名(self): #self指调用该函数的对象
代码
#创建对象
对象名 = 类名()类外面添加对象属性:
1
对象名.属性名 = 值
类外面获取对象属性:
1
对象名.属性名
类里面获取对象属性:
1
self.属性名
综合实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Washer():
def wash(self):
print('wash the clothes!')
def get_size(self):
print(f'此洗衣机的尺寸是{self.width} X {self.height}')
haier1 = Washer()
haier1.width = 500
haier1.height = 300
haier2 = Washer()
haier2.width = 600
haier2.height = 400
print(haier1.width)
haier1.get_size()
haier2.get_size()魔法方法: __init__() 、 __str__()、__del__()。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#1. __init__() 初始化对象。
#创建对象时默认被调用;不需开发者传递self参数,python解释器会自动把当前对象引用传递过去。
class washer():
def __init__(self,width,height):
self.width = width
self.height = height
def print_info(self):
print(f'{self.width} X {self.height}')
h = washer(500,800)
h.print_info()
#输出结果 500 X 800
#2. __str__() 使得用print输出对象时,输出该方法中return的数据,而不再输出对象的内存地址。
def __str__(self):
return "这是洗衣机对象!"
print(h)
#输出结果 这是洗衣机对象!
#3. __del__() 当删除对象时,python解释器会默认调用__del__()方法
def __del__(self):
print(f'{self}对象已经被删除!')
del h
#输出结果 <__main__.washer object at 0x000002531DF744F0>对象已经被删除!
两个案例:
烤地瓜
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#需求:1.被烤时间和地瓜状态相对应 2.用户可按意愿添加调料
class SweetPotato():
def __init__(self):
self.cook_time=0
self.cook_state='生的'
self.condiments=[]
def cook(self, time):
if time >=0:
self.cook_time += time
if 0<= self.cook_time < 3:
self.cook_state = '生的'
elif 3 <= self.cook_time < 5:
self.cook_state = '半生不熟'
elif 5 <= self.cook_time < 8:
self.cook_state = '熟了'
elif self.cook_time >= 8:
self.cook_state = '糊了!'
else:
print('时间刺客?!')
def add_condiment(self, con):
self.condiments.append(con)
def __str__(self):
return f'这个地瓜烤了{self.cook_time}分钟,状态是{self.cook_state},添加的调料有{self.condiments}'
p = SweetPotato()
p.add_condiment('番茄酱')
print(p)
p.cook(8)
p.add_condiment('芥末')
print(p)
# 这个地瓜烤了0分钟,状态是生的,添加的调料有['番茄酱']
# 这个地瓜烤了8分钟,状态是糊了!,添加的调料有['番茄酱', '芥末']搬家具
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#需求 将小于房子剩余面积的家具摆放到房子中
class Furniture():
def __init__(self,name,area):
self.name = name
self.area = area
class House():
def __init__(self,adress,area):
self.adress = adress
self.area = area
self.free_area = area
self.furniture = []
def add_furniture(self,item):
if self.free_area >= item.area:
self.furniture.append(item.name)
self.free_area -= item.area
else:
print('家具太大,剩余面积不足,无法容纳')
def __str__(self):
return f'这个房子的地址是{self.adress},总面积是{self.area},当前剩余面积是{self.free_area},家具有{self.furniture}'
bed = Furniture('双人床',6)
sofa = Furniture('沙发',10)
court = Furniture('高尔夫球场',1000)
house = House('陆家嘴',200)
print(house)
house.add_furniture(bed)
house.add_furniture(sofa)
house.add_furniture(court)
print(house)
#这个房子的地址是陆家嘴,总面积是200,当前剩余面积是200,家具有[]
#家具太大,剩余面积不足,无法容纳
#这个房子的地址是陆家嘴,总面积是200,当前剩余面积是184,家具有['双人床', '沙发']继承: Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法,具体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#定义父类A
class A(object):
def __init__(self):
self.num = 1
def infor_print(self):
print(self.num)
#定义子类B,继承父类A
class B(A):
pass
#创建对象,验证对象继承
result = B()
result.info_print()在python中,所有类默认继承object类,object类是顶级类或基类;其他子类叫派生类。
拓展:python2中的经典类 和 python3中的新式类
1
2
3
4
5
6
7
8
9
10
11#经典类(不由任意内置类型派生出的类)
class 类名:
代码
......
#新式类
class 类名(object):
代码
......
#在今后的学习和运用中,统一使用新式类单继承:一个子类继承一个父类,这种单一的继承关系称为单继承。
多继承:一个子类同时继承多个父类。
1
2class 子类(父类A,父类B,父类C)
#当两个父类中的属性和方法有同名时,优先继承第一个父类中的同名属性和方法,即继承A类。子类重写父类同名属性与方法:在子类中可以重写与父类中同名的属性和方法。子类创建的对象调用属性和方法时,会调用子类中重写的属性和方法。
拓展: __mro__顺序 方法查看类的继承层级顺序。
1
print(类名.__mro__)
子类调用父类同名属性和方法:在子类中重写了父类中同名属性与方法的情况下,调用父类中的同名属性和方法。
1
2
3
4
5
6
7
8
9
10class 子类B(父类A):
def 同名方法(self):
#如果之前调用了父类的属性和方法,则父类属性会覆盖子类属性,故在调用子类属性前,先调用子类自己的初始化
self.__init__(self)
代码
def 调用父类方法(self):
#调用父类方法,为保证调用到的属性也是父类的属性,必须在调用方法前调用父类的初始化
父类A.__init__(self)
父类A.同名方法(self)多层继承:一般指大于两层的继承关系。
1
2
3
4
5
6
7
8class A(object):
...
class B(A):
...
class C(B): #多层继承
...super()调用父类方法:自动查找父类,直接调用父类的属性方法,调用顺序遵循__mro__类属性的顺序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class A(object)
class B(A)
class C(B):
#方法一:原始方法
def useAB(self):
A.__init__(self)
A.同名方法(self)
B.__init__(self)
b.同名方法(self)
#方法二:super()方法
#方法2.1 super(当前类名,self).函数()
def useAB(self):
super(C,self).__init__()
super(C,self).同名方法()
#此时会调用父类B的方法;若想调用A类的方法,需要在B类的同名方法中添加同样的super方法代码来调用A类
#方法2.2 super().函数()
def useAB(self):
super().__init__(self)
super().同名方法()
#同样调用父类B的方法;无法直接调用父类的父类A的属性和方法私有权限
设置私有属性和方法:在属性名和方法名前面加上两个下划线。
私有属性和私有方法只能在类内访问和修改,即子类无法继承或直接访问父类的私有属性和方法。
1
2
3
4
5
6
7class A(object):
def __init__(self):
self.name = 'A'
self.__money = 99999 #私有属性
def __CostMoney(self,money): #私有方法
self.__money -= money获取和修改私有属性值:可在类内定义公有函数来获取和修改 私有属性值,在类外调用该函数来实现获取和修改私有属性功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#一般在类内用函数名get_xx来获取私有属性,用set_xx来修改私有属性
class A(object):
def __init__(self):
self.__money = 99999
def get_money(self):
return self.__money
def set_money(self,new_money):
self.__money = new_money
class B(A):
pass
b = B()
b.get_money() #成功获取父类中的私有属性
b.set_money(0) #成功修改父类中的私有属性多态:一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果。即传入不同的对象,产生不同的结果。
类属性和实例属性:类属性即类所拥有的属性,它为该类所有对象共有。类属性可以用 类对象 或 实例对象 访问。
类属性只能通过类对象修改。
1
2#修改类属性
类名.属性 = 值类方法:需要用装饰器
@classmethod
来标识其为类方法,类方法第一个参数必须是类对象,一般以cls
作为第一个参数。1
2
3
4
5
6
7
8
9class A(object):
__num = 777
def get_num(cls):
return cls.__num
obj = A()
print(obj.get_num())静态方法:通过装饰器
@staticmethod
进行修饰,静态方法即不需要传递类和对象的方法,有利于减少不必要的内存占用和性能消耗。1
2
3
4class A(object):
def info_print():
print('这是A类')
六.异常
异常的定义:解释器检测到错误时无法继续执行,并出现一些错误的提示,这就是所谓的异常。
异常的作用:使得解释器检测到错误时,转而执行另一句没错误的语句,使得程序不因一个错误而停止下来。
基本写法:
1
2
3
4
5
6
7
8try:
可能发生错误的代码
except:
出现异常时执行的代码
else:
没有异常时执行的代码
finally:
无论是否异常都要执行的代码体验案例:
1
2
3
4
5#需求:尝试以r模式打开文件,若文件不存在(发生错误),则以w方式打开
try:
f = open('test.txt','r')
except:
f = open('test.txt','w')捕获指定异常:
1
2
3
4
5
6
7
8
9try:
print(num)
except (NameError, ZeroDivisionError) as result:
print(result) #捕获的异常描述信息
num = 777
print(num)
#若尝试执行代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
#一般try下方只放一行尝试执行的代码捕获所有异常:利用 Exception 类
1
2
3
4
5#Exception是所有程序异常类的父类
try:
可能错误的代码
except Exception as result:
print(result)异常中的 else 和 finally:
1
2
3
4
5
6
7
8
9try:
f = open('test.txt','r')
except Exception as result:
f = open('test.txt','w')
print(result)
else: # try 下方的代码无异常时执行的代码
print('代码没有异常和错误')
finally: #无论有无异常都要执行的代码,如关闭文件
f.close()异常的传递:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import time
try:
f = open('test.txt') #默认打开模式为只读
#尝试循环读取内容
try:
while True:
con = f.readline()
#无内容时退出循环
if len(con) == 0:
break
time.sleep(2)
print(con)
except:
#在命令提示符中按下 Ctrl+C 终止程序
print('程序被意外终止')
except:
print('文件不存在')自定义异常: 抛出自定义异常的语法为
raise 异常类对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#自定义异常类,继承Exception
class ShortInputError(Exception):
def __init__(self,length,min_length):
self.length=length
self.min_length=min_length
#设置抛出异常的描述信息
def __str__(self):
return f'输入长度为{self.length},不能少于{self.min_length}个字符'
def main(): #封装代码
try:
con = input('请输入密码: ')
if len(con) < 6:
raise ShortInputError(len(con),6)
except Exception as result:
print(result)
else:
print('密码输入完成')
main()
七.模块
了解模块:Python模块(Module),是一个Python文件,包含了Python对象定义和语句。
导入和调用模块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#导入及调用模块
#写法一
import 模块名 #导入模块中的所有代码
模块名.功能名()
#写法二
from 模块名 import 功能1,功能2... #单个调用某功能
功能名() #即不需要在功能前写 "模块名."
#写法三
from 模块名 import *
功能名()
#一般用第一种写法利用as定义别名:定义别名后,使用时要用定义的别名
1
2
3
4
5#模块定义别名
import 模块名 as 别名
#功能定义别名
from 模块名 import 功能 as 别名制作模块:模块名字就是py文件的名字。自定义模块名必须要符合标识符命名规则。
1
2
3
4#只会在当前文件中调用下列测试代码,其他导入的文件内不符合该条件,也就不会执行测试代码
# __name__ 是系统变量,是模块的标识符。如果在自身模块里,则其值为 '__main__';否则是所在模块的名字
if __name__ == '__main__':
测试模块功能代码模块定位顺序:当导入一个模块,Python解释器对模块位置的搜索顺序是:
当前目录 > 搜索在shell变量PYTHONPATH下的每个目录 > 操作系统的默认python路径
注意:
自己的文件名不要和已有模块名重复,否则模块功能无法使用。
使用
from 模块名 import 功能
时,若功能名字重复,则调用最后定义的或最后导入的功能。当使用
import 模块名
的写法调用模块时,不需要担心功能名重复。__all__
列表:如果一个模块文件中有__all__
变量列表,当使用from 模块名 import *
导入该模块时,则只能导入__all__
列表中的元素。包:包将有联系的模块组织在一起,放到同一个文件夹下,并且在这个文件夹内自动生成一个名字为
__init__.py
的文件,这个文件控制着包的导入行为。创建包:在Pycharm中 New -> Python Package -> 输入包名 - > [OK] 即可新建一个包。
导入包:
1
2
3
4
5
6
7
8#方法一
import 包名.模块名
包名.模块名.功能
#方法二
#注意,必须在 __init__.py 文件中添加 __all__ = [] 来控制允许导入的模块列表
from 包名 import *
模块名.功能
八.面向对象综合实例
1 | #使用面向对象编程思想完成学员管理系统的开发 |
- 本文作者: Squidward
- 本文链接: http://www.squidward.xyz/2020/10/27/Python基础/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!