Python 基础入门学习
一.基本语句
-
注释:
#
单行注释"""
多行注释"""
-
print (" ")
输出函数 -
基本运算符:
+
-
*
/
//
(取整)%
(取余)**
(幂运算) -
变量的定义:
变量名 = 值
(每个变量使用前都必须赋值,变量在赋值以后才会被创造,定义时不需要指定变量类型) -
type( )
查看变量类型函数 -
input( )
变量输入函数 用法举例: a = input(“输入数字:”) 输入的任何内容的数据类型默认为字符型str -
int(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和空格一定不能混用!
if 条件1: 条件1成立时要执行的代码 elif 条件2: 条件2成立时要执行的代码 else: 条件1、2都不成立时执行的代码
-
if语句训练:猜拳游戏
#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
(随机整数) 功 如:import random num = random.randint(0,2)
(num为0、1、2中的随机一个数)
-
三目运算符:
条件成立时的表达式 if 条件 else 条件不成立时的表达式
如:
MaxNum = a if a>b else b
-
While 循环:
while 条件: 条件成立时重复执行的代码
注意: 计数的初始值习惯写为0
-
break 和 continue :
break
为终止循环,即不再循环continue
为退出当前一次循环而直接执行下一次循环,即跳入下一次循环 -
for 循环:
for 临时变量 in 序列: 重复执行的代码
-
while 与 else : 如果循环由 break 停止,则else下的代码不执行,for 与 else 的用法与此类似
while 条件: 条件成立时重复执行的代码 else: 循环正常结束之后执行的代码
二.基本数据类型
-
字符串可以用单引号、双引号、三引号括起来,字符串为不可变类型。
-
python中每个字符串自带下标和索引,可用
str[x]
来精确访问字符串 str 中的某个字符 -
切片: 指对 字符串、列表、元组 进行截取其中一部分的操作
语法: 序列[开始位置下标 : 结束位置下标 : 步长]
其中切片不包含结束位置下标对应的数据 ,即开始位置下标和结束位置下标为 [ ) 的包含形式
下标 和 步长 均可不写或写负数,步长默认为1,若下标开始到结束的方向与步长的方向冲突,则无法选取出数据
-
字符串的查找: find() 、index() 、count() 、rfind() 、rindex()
find()
: 检测某个子串是否包含在这个字符串中,如果存在则返回这个子串开始位置的下标,否则返回-1字符串序列.find( 子串 , 开始位置下标 , 结束位置下标 )
开始和结束位置下标可以省略,表示在整个字符串序列中查找
index()
: 与find()函数的用法一样,但如果不存在要查找的子串,则会报错count()
:返回某子串在该字符串中出现的次数,若不存在则返回0rfind()
与rindex()
查找方向为从右侧开始,其功能与 find() 与 index() 相同 -
字符串的替换 :replace() 替换
字符串序列.replace ( 旧子串、新子串、替换次数 )
注意: replace函数并不会改变原有字符串的数据,修改后的数据是replace函数的返回值
-
字符串的分割: split() 分割,返回一个列表,丢失分割字符
字符串序列.split(分割字符,分割次数)
注意:split函数也不会改变原有字符串数据,修改后的数据为函数返回值
-
列表的合并:join() 合并,返回一个字符串,添加连接字符
连接字符串.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()
返回 一个原字符串 左/右/中 对齐,并用指定字符(默认空格)填充至对应长度的新字符串
字符串序列.ljust( 长度 , 填充字符 ) 字符串序列.rjust( 长度 , 填充字符 ) 字符串序列.center( 长度 , 填充字符 )
例:
initial: brother and me
ljust: brother and me----------------
rjust: ----------------brother and me
center: --------brother and me-------- -
字符串判断开头或结尾函数:
startswith()
: 检查字符串是否以指定子串开头,是则返回True,否则返回False。如果设置开始和结束位置下标,则在指定范围内检查字符串序列.startswith(子串,开始位置下标,结束位置下标)
endswith()
: 检查字符串是否以指定子串结尾,用法与 startswith()相同字符串序列.endswith(子串,开始位置下标,结束位置下标)
-
字符串字符类型判断函数:
isalpha()
: 如果字符串非空且只包含字母则返回True , 否则返回Falseisdigit()
: 如果字符串非空且只包含数字则返回True , 否则返回Falseisalnum()
: 如果字符串非空且只包含数字或字母则返回True, 否则返回Falseisspace()
: 如果字符串非空且只包含空格则返回True , 否则返回False -
列表 : 可以用下标选取指定数据,列表为可变类型。
-
列表数据查找函数:
index()
: 返回指定数据所在位置的下标,若数据不存在则报错列表序列.index(数据, 开始位置下标, 结束位置下标)
count()
: 返回指定数据在该列表出现的次数,若数据不存在则返回0列表序列.count(数据)
len()
: 返回列表的长度,即列表中数据的个数len(列表序列)
-
判断列表中是否存在指定数据:
in
: 判断指定数据在某个序列的存在,存在返回True,否则返回False'指定数据' in 列表序列
not in
: 与 in 的用法相同,返回结果相反 -
列表数据增加函数:
append()
: 列表结尾追加数据,若数据为一个序列,则直接追加整个序列到列表的结尾位置列表序列.append(数据)
extend()
: 列表结尾追加数据,若数据为一个序列,则将序列的数据逐一添加到列表,若数据为字符串,则将单独的每个字符逐一添加到列表列表序列.extend(数据)
insert()
: 指定位置新增数据,增添方式与 append() 相同列表序列.insert(位置下表,数据)
-
列表数据删除函数:
del 目标(列表名 或 列表指定下标数据)
pop()
: 删除指定下标的数据(默认为最后一个),并返回该数据。列表序列.pop(下标)
remove()
: 移除列表中某个数据的第一个匹配项,若匹配失败则报错列表序列.remove(数据)
clear()
: 清空列表中的所有数据列表序列.clear()
-
列表数据修改函数:
修改指定下标数据: 列表序列[下标] = 数据
reverse()
: 将列表数据的顺序逆置列表序列.reverse()
sort()
: 对列表的数据进行排序列表序列.sort( key = None, reverse = False)
注意: reverse = True 降序 reverse = False 升序(默认)
-
列表数据复制函数:
copy()
: 列表数据复制新列表序列 = 原列表序列.copy()
即将原列表的数据复制到新列表中
-
列表的循环遍历:
while循环方法 :
i = 0 while i < len(list): print(list[i]) i += 1
for循环方法 :
for i in list: print(i)
-
列表嵌套:指一个列表里包含了其他的子列表。
例:
List = [ ['a' , 'b' , 'c'] , ['1' , '2' , '3'] , ['&' , '$' , '%'] ]
-
列表综合训练:
#将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’ 数据
-
字典:字典里的数据是以键值对形式存储的。字典为可变类型。
特点: 符号为大括号,数据为键值对形式出现,各个键值对之间用逗号隔开。
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()
: 获取某个键对应的值字典序列.get(key , 默认值)
注意:若当前查找的key不存在则返回默认值,若默认值省略不写则返回None
keys()
: 获取字典中所有的key,并返回可迭代对象字典序列.keys()
values()
: 获取字典中所有的values,并返回可迭代对象字典序列.values()
items()
: 获取字典中所有的键值对(key 和 values),并返回可迭代对象 ,里面的数据是元组字典序列.items()
-
字典的循环遍历:
遍历字典的Key:
for key in dict1.keys(): print(key)
遍历字典的Value:
for value in dict1.values(): print(value)
遍历字典的元素:
for item in dict1.items(): print(item)
遍历字典的键值对(拆包):
for 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循环中enumerate(可遍历对象, start=0)
容器类型转换:
tuple(序列)
: 将某个序列转换成元组list(序列)
: 将某个序列转换成列表set(序列)
: 将某个序列转换成集合 -
推导式(生成式): 列表推导式、字典推导式、集合推导式
作用: 化简代码
列表推导式:用一个表达式创建一个有规律的列表或控制一个有规律列表。
创建0-10的列表:
list = [i for i in range(10)]
创建0-10的偶数列表:
list = [i for i in range(10) if i % 2 == 0]
多个for循环列表:
list = [(i , j) for i in range(3) for j in range(3)]
字典推导式:快速合并列表为字典或提取字典中目标数据
赋值体验:
dict = { i:i*2 for i in range(1,5)}
将两个列表合并为字典:
list1 = ['name' , 'age' , 'gender'] list2 = ['Tom' , 20 , 'man'] dict = { list1[i] : list2[i] for i in range(len(list1)) }
提取字典中目标数据:
counts = { 'a' : 150 , 'b' : 200 , 'c' : 250} count = { key : value for key , value in counts.items() if value >= 200}
集合推导式:
list = [1,1,2] set = { i * 2 for i in list}
三.函数
-
函数:
def 函数名(参数):
“”" 说明文档内容 “”"
代码1
代码2
…
注意:参数可有可无,必须先定义后使用
函数中return之后的代码并不会执行
help(函数名) 查看函数解释说明的信息
-
函数(二):
局部变量:只在函数体内部生效的变量
全局变量:指在函数体内、外都能生效的变量
在函数体内部修改全局变量:在函数体内部用 global 声明变量为全局变量后修改
函数有多个返回值时: return 后面可以直接书写 元组、列表、字典,返回多个值
位置参数:调用函数时根据函数定义的参数位置来传递参数,传递和定义参数的顺序及个数必须一致
关键字参数:函数调用时,通过“键=值”的形式加以指定传参,关键字参数之间不存在先后顺序
缺省参数:也叫默认参数,用于在定义函数时为参数提供默认值,调用函数时可以不传入有默认值的参数。在定义和调用函数时,位置参数必须在缺省参数之前
不定长参数:也叫可变参数,用于不确定调用时会传递多少个参数的场景,可用 包裹位置参数 或 包裹关键字参数 来进行参数传递
包裹位置传递(元组):
def 函数名( *args ): print( args ) 函数名( 'abc' , 123 )
包裹关键字传递(字典):
def 函数名( **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)
不可变类型:整型、浮点型、字符串、元组
-
函数加强应用—学员管理系统:
#定义功能界面函数 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~n的累加和 def num(n): #出口 if n == 1: return 1 #函数内部自己调用自己 return n+num(n-1)
若没有出口,则报错提示超出最大递归深度(996)。
-
lambda表达式(匿名函数)
:应用场景: 化简代码。如果一个函数只有一个返回值,并且只有一句代码,可以使用lambda简化。
lambda 参数列表: 表达式
lambda表达式的参数列表可有可无,函数的参数在lambda表达式中完全适用。
lambda表达式能够接收任何数量的参数但只能返回一个表达式的值。
#计算 a+b 的lambda实现 fn = lambda a,b: a+b print(fn(1,2)) #输出结果: 3
lambda的参数形式:无参、有参、缺省参数(默认)、可变参数*args、可变参数**kwargs。
#无参 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: kwargs
lambda的应用:
#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():对数字进行四舍五入
def 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)返回。#计算list1序列中各个数字的三次方 list1 = [1,2,3,4,5] def func(x): return x ** 3 result = map(func, list1) #此时result为map返回的迭代器 print(result) #将返回迭代器result的地址 print(list(result)) #[1, 8, 27, 64, 125]
reduce(func, list)
:functools模块中的一个高阶函数,其中func必须有两个参数。每次func结算的结果继续和序列的下一个元素做累积计算。#计算list2序列中各个数字的累加和 import functools #导入模块 list2 = [1,2,3,4,5] def func(a,b): return a+b result = functools.reduce(func,list2) print(result) #15
filter(func, list)
:用于过滤序列,过滤掉不符合条件的元素,并返回一个filter对象。可用 list() 转换为列表。#过滤list3序列中所有的偶数,只留下奇数 list3 = [1,2,3,4,5,6,7,8,9] def func(x): return x%2 != 0 result = filter(func,list3) result = list(result) print(result) #[1,3,5,7,9]
四.文件操作
-
文件操作:
作用:把一些内容(数据)存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力。
文件操作步骤:打开文件、读写等操作、关闭文件。
open()
:打开一个已经存在的文件,或创建一个新文件。f = open(name, mode) #name: 是要打开的目标文件名的字符串(可以包含文件所在的具体路径) #mode: 设置打开文件的模式(访问模式):只读、写入、追加等 #此时f为name文件的文件对象,可通过f执行之后的读写等操作
主访问模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式(访问模式未指定时,即为只读模式)。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 (b) 以二进制形式读取 (+) 可读可写 访问模式r+、w+、a+的区别:
r+
:没有该文件则报错,文件指针在开头故能读取数据w+
:没有该文件会新建,文件指针在开头并会用新内容覆盖原有内容,故无法读取文件内原有的数据a+
:没有该文件会新建,文件指针在结尾故不能读取数据写入内容:write()
文件对象.write('内容')
读取内容:read()、readlines()、readline()。
文件对象.read(num) #num 表示要从文件中读取的数据的长度。不写则默认读取所有数据。其中换行符'\n'会占一位 文件对象.readnlines() #按照行的方式把整个文件的内容进行一次性读取,并返回一个列表,其中每一行数据为一个元素 文件对象.readline() #一次读取一行内容、重复调用readline()则依次读取文件中每一行的内容
移动文件指针:seek()
文件对象.seek(偏移量,起始位置) #起始位置参数: 0开头 1当前 2结尾
应用:
#使用 a 访问模式打开文件,通过改变文件指针位置来读取数据 f = open('test.txt','a') f.seek(0,0) #此时可简写为 f.seek(0) con = f.read() f.close()
-
文件备份案例:
#用户输入当前目录下任意文件名,程序完成对该文件的备份功功能(备份文件名为 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 模块
import os #1.文件操作 #文件重命名,也可以重命名文件夹 os.rename(目标文件名或路径, 新文件名) #文件删除,也可以删除文件夹 os.remove(目标文件名) #2.文件夹操作 #创建文件夹 os.mkdir(文件夹名字) #删除文件夹 os.rmdir(文件夹名字) #3.目录操作 #获取当前目录 os.getcwd() #改变当前默认目录 os.chdir(目录文件夹) #获取目录列表 os.listdir(目录文件夹)
-
文件和文件夹操作应用案例:
#批量修改文件名,既可添加指定字符串,又能删除指定字符串 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)
五.面向对象
-
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。对象是由类创建出来的真实存在的事物。
#创建类 class 类名(): #类名要满足标识符命名规则,同时遵循大驼峰命名习惯 代码 ...... def 函数名(self): #self指调用该函数的对象 代码 #创建对象 对象名 = 类名()
-
类外面添加对象属性:
对象名.属性名 = 值
类外面获取对象属性:
对象名.属性名
类里面获取对象属性:
self.属性名
综合实例:
class 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. __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.用户可按意愿添加调料 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分钟,状态是糊了!,添加的调料有['番茄酱', '芥末']
搬家具
#需求 将小于房子剩余面积的家具摆放到房子中 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面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法,具体如下:
#定义父类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中的新式类
#经典类(不由任意内置类型派生出的类) class 类名: 代码 ...... #新式类 class 类名(object): 代码 ...... #在今后的学习和运用中,统一使用新式类
单继承:一个子类继承一个父类,这种单一的继承关系称为单继承。
多继承:一个子类同时继承多个父类。
class 子类(父类A,父类B,父类C) #当两个父类中的属性和方法有同名时,优先继承第一个父类中的同名属性和方法,即继承A类。
子类重写父类同名属性与方法:在子类中可以重写与父类中同名的属性和方法。子类创建的对象调用属性和方法时,会调用子类中重写的属性和方法。
拓展: **__mro__**顺序 方法查看类的继承层级顺序。
print(类名.__mro__)
子类调用父类同名属性和方法:在子类中重写了父类中同名属性与方法的情况下,调用父类中的同名属性和方法。
class 子类B(父类A): def 同名方法(self): #如果之前调用了父类的属性和方法,则父类属性会覆盖子类属性,故在调用子类属性前,先调用子类自己的初始化 self.__init__(self) 代码 def 调用父类方法(self): #调用父类方法,为保证调用到的属性也是父类的属性,必须在调用方法前调用父类的初始化 父类A.__init__(self) 父类A.同名方法(self)
多层继承:一般指大于两层的继承关系。
class A(object): ... class B(A): ... class C(B): #多层继承 ...
super()调用父类方法:自动查找父类,直接调用父类的属性方法,调用顺序遵循__mro__类属性的顺序。
class 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的属性和方法
-
私有权限
**设置私有属性和方法:在属性名和方法名 **前面加上两个下划线。
私有属性和私有方法只能在类内访问和修改,即子类无法继承或直接访问父类的私有属性和方法。
class A(object): def __init__(self): self.name = 'A' self.__money = 99999 #私有属性 def __CostMoney(self,money): #私有方法 self.__money -= money
获取和修改私有属性值:可在类内定义公有函数来获取和修改 私有属性值,在类外调用该函数来实现获取和修改私有属性功能。
#一般在类内用函数名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) #成功修改父类中的私有属性
-
多态:一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果。即传入不同的对象,产生不同的结果。
-
类属性和实例属性:类属性即类所拥有的属性,它为该类所有对象共有。类属性可以用 类对象 或 实例对象 访问。
类属性只能通过类对象修改。
#修改类属性 类名.属性 = 值
-
类方法:需要用装饰器
@classmethod
来标识其为类方法,类方法第一个参数必须是类对象,一般以cls
作为第一个参数。class A(object): __num = 777 @classmethod def get_num(cls): return cls.__num obj = A() print(obj.get_num())
-
静态方法:通过装饰器
@staticmethod
进行修饰,静态方法即不需要传递类和对象的方法,有利于减少不必要的内存占用和性能消耗。class A(object): @staticmethod def info_print(): print('这是A类')
六.异常
-
异常的定义:解释器检测到错误时无法继续执行,并出现一些错误的提示,这就是所谓的异常。
异常的作用:使得解释器检测到错误时,转而执行另一句没错误的语句,使得程序不因一个错误而停止下来。
-
基本写法:
try: 可能发生错误的代码 except: 出现异常时执行的代码 else: 没有异常时执行的代码 finally: 无论是否异常都要执行的代码
体验案例:
#需求:尝试以r模式打开文件,若文件不存在(发生错误),则以w方式打开 try: f = open('test.txt','r') except: f = open('test.txt','w')
-
捕获指定异常:
try: print(num) except (NameError, ZeroDivisionError) as result: print(result) #捕获的异常描述信息 num = 777 print(num) #若尝试执行代码的异常类型和要捕获的异常类型不一致,则无法捕获异常 #一般try下方只放一行尝试执行的代码
-
捕获所有异常:利用 Exception 类
#Exception是所有程序异常类的父类 try: 可能错误的代码 except Exception as result: print(result)
-
异常中的 else 和 finally:
try: f = open('test.txt','r') except Exception as result: f = open('test.txt','w') print(result) else: # try 下方的代码无异常时执行的代码 print('代码没有异常和错误') finally: #无论有无异常都要执行的代码,如关闭文件 f.close()
-
异常的传递:
import 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 异常类对象
#自定义异常类,继承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对象定义和语句。
-
导入和调用模块:
#导入及调用模块 #写法一 import 模块名 #导入模块中的所有代码 模块名.功能名() #写法二 from 模块名 import 功能1,功能2... #单个调用某功能 功能名() #即不需要在功能前写 "模块名." #写法三 from 模块名 import * 功能名() #一般用第一种写法
利用as定义别名:定义别名后,使用时要用定义的别名
#模块定义别名 import 模块名 as 别名 #功能定义别名 from 模块名 import 功能 as 别名
-
制作模块:模块名字就是py文件的名字。自定义模块名必须要符合标识符命名规则。
#只会在当前文件中调用下列测试代码,其他导入的文件内不符合该条件,也就不会执行测试代码 # __name__ 是系统变量,是模块的标识符。如果在自身模块里,则其值为 '__main__';否则是所在模块的名字 if __name__ == '__main__': 测试模块功能代码
-
模块定位顺序:当导入一个模块,Python解释器对模块位置的搜索顺序是:
当前目录 > 搜索在shell变量PYTHONPATH下的每个目录 > 操作系统的默认python路径
注意:
自己的文件名不要和已有模块名重复,否则模块功能无法使用。
使用
from 模块名 import 功能
时,若功能名字重复,则调用最后定义的或最后导入的功能。当使用
import 模块名
的写法调用模块时,不需要担心功能名重复。 -
__all__
列表:如果一个模块文件中有__all__
变量列表,当使用from 模块名 import *
导入该模块时,则只能导入__all__
列表中的元素。 -
包:包将有联系的模块组织在一起,放到同一个文件夹下,并且在这个文件夹内自动生成一个名字为
__init__.py
的文件,这个文件控制着包的导入行为。创建包:在Pycharm中 New -> Python Package -> 输入包名 - > [OK] 即可新建一个包。
导入包:
#方法一 import 包名.模块名 包名.模块名.功能 #方法二 #注意,必须在 __init__.py 文件中添加 __all__ = [] 来控制允许导入的模块列表 from 包名 import * 模块名.功能
八.面向对象综合实例
#使用面向对象编程思想完成学员管理系统的开发
#为了方便维护代码,一般一个角色一个程序文件
#项目要有主程序入口,习惯为main.py
#系统要求:学员数据存储在文件中
#系统功能:添加学员、删除学员、修改学员信息、查询学员信息、显示所有学员信息、保存学员信息、退出系统等功能
#student.py
#学员类
class Student(object):
def __init__(self,name,gender,tel):
#姓名、性别、手机号
self.name = name
self.gender = gender
self.tel = tel
def __str__(self):
return f'{self.name},{self.gender},{self.tel}'
#mangerSystem.py
#存储数据的: student.data
#存储数据的形式: 列表存储学员对象
#系统功能: 添加、删除、修改、查询、显示、保存学员信息
#管理系统类
class StudentManager(object):
def __init__(self):
#存储数据所用列表
self.student_list = []
#一. 程序入口函数,启动程序后执行的函数
def run(self):
#1. 加载学员信息
self.load_student()
while True:
#2. 显示功能菜单
self.show_menu()
#3. 用户输入目标功能序号
menu_num = int(input('请输入您需要的功能序号: '))
#4. 根据用户输入的序号执行相应功能
if menu_num == 1:
# 添加学员
self.add_student()
elif menu_num == 2:
# 删除学员
self.del_student()
elif menu_num == 3:
# 修改学员信息
self.modify_student()
elif menu_num == 4:
# 查询学员信息
self.search_student()
elif menu_num == 5:
# 显示所有学员信息
self.show_menu()
elif menu_num == 6:
# 保存学员信息
self.save_student()
elif menu_num == 7:
# 退出系统 - 退出循环
break
#二. 系统功能函数
#2.1 显示功能菜单 -- 静态方法
@staticmethod
def show_menu():
print('请选择如下功能: ')
print('1.添加学员')
print('2.删除学员')
print('3.修改学员信息')
print('4.查询学员信息')
print('5.显示所有学员信息')
print('6.保存学员信息')
print('7.退出系统')
#2.2 添加学员
def add_student(self):
#1. 用户输入
name = input('请输入姓名: ')
gender = input('请输入性别: ')
tel = input('请输入手机号: ')
#2. 创建学员对象 -- 先导入student.py模块
student = Student(name,gender,tel)
#3. 将对象添加到学员列表
self.student_list.append(student)
#2.3 删除学员
def del_student(self):
#1. 用户输入目标学员姓名
del_name = input('请输入要删除的学员姓名:')
#2. 如果用户输入的目标学员存在则删除,否则提示不存在
for i in self.student_list:
if i.name == del_name:
self.student_list.remove(i)
break
else:
print('查无此人!')
#2.4 修改学员信息
def modify_student(self):
#1. 用户输入目标学员姓名
modify_name = input('请输入要修改的学员姓名: ')
#2. 如果用户输入的目标学员存在,则修改信息,否则提示不存在
for i in self.student_list:
if i.name == modify_name:
i.name = input('请输入学员姓名: ')
i.gender = input('请输入学员性别: ')
i.tel = input('请输入学员手机号: ')
print('修改成功!')
break
else:
print('查无此人!')
#2.5 查询学员信息
def search_student(self):
#1. 用户输入目标学员姓名
search_name = input('请输入要查询的学员姓名: ')
#2. 若存在,打印学员信息,否则提示不存在
for i in self.student_list:
if i.name == search_name:
print(f'姓名{i.name},性别{i.gender},手机号{i.tel}')
break
else:
print('查无此人!')
#2.6 显示所有学员信息
def show_student(self):
print('姓名\t性别\t手机号')
for i in self.student_list:
print(f'{i.name}\t{i.gender}\t{i.tel}')
#2.7 保存学员信息
def save_student(self):
# 拓展 __dict__方法,以字典方式返回类和对象内的属性
#1. 打开文件
f = open('student.data','w')
#2. 文件写入学员数据 - 先将学员对象数据转换成列表字典数据再做存储
new_list = [i.__dict__ for i in self.student_list]
# 文件内数据要求为字符串类型,故要先转换数据类型为字符串才能写入文件
f.write(str(new_list))
#3. 关闭文件
f.close()
#2.8 加载学员信息
def load_student(self):
#尝试以"r"模式打开数据文件,有异常则用"w"模式打开;存在则读取数据
try:
f = open('student.data','r')
except:
f = open('student.data','w')
else:
#1. 读取数据
data = f.read()
#2. 先将文件中的 字符串型字典数据 转换为 对象数据 后再存储到学员列表
new_list = eval(data)
self.student_list = [Student(i['name'],i['gender'],i['tel']) for i in new_list]
finally:
#3. 关闭文件
f.close()
#main.py
#导入模块
#from managerSystem import *
#启动管理系统
#if __name__ == '__main__':
student_manager = StudentManager()
student_manager.run()
来源:oschina
链接:https://my.oschina.net/u/4411637/blog/4682451