python学习笔记
2021-08-27 11:35:19 190 举报
AI智能生成
自己整理的python学习笔记
作者其他创作
大纲/内容
Python常用模块
时间模块
time模块
time.time() 返回时间戳
time.ctime([secs]) 返回本地时间,格式为字符串
不带secs,返回当前时间,格式为字符串
带secs,返回自1970, 00:00:00后多少秒的时间
time.gmtime([secs]) 返回标准时间,格式为元组【struct_time()】
不带secs,返回当前UTC时间,比本地晚八小时
带secs,返回自1970后多少秒的时间,格式为struct_time,时间元组。
time.localtime([secs]) 返回本地时间,格式为元组
不带secs,返回当前本地时间
带secs,返回自1970后多少秒的本地时间。
time.mktime(t) 将制定时间转换成时间戳
time.mktime(time.localtime()) --> 1553674488.0
time.asctime(t) 将标准时间strcut_time,gtime,localtime,strptime的返回值,转变成时间字符串。无参数,返回当前时间。
time.strftime(format[, t]) 将时间类型格式化为字符串
主要的时间格式符
查看
年-月-日【%Y-%m-%d】
年:Y(2019)---y(19)
月:
m【数字月份01-12】
B【月份全称】b【月份简称】
日:d【01-31】
时:分:秒【%H:%M:%S】
时
H【24小时】
I【12小时】
分
M【00-59】
秒
S【00-59】
其他
上午下午
P【pm,am】
全年第多少天
j【000-365】
全年第多少周
U【00-53】
W【00-53】
星期几
w【0-6】
A a :星期的全称(A)和简写(a)
标准的时间字符串
X -->16:48:58
标准的日期字符串
x --> 03/27/19
标准的时间日期字符串
c -->'Wed Mar 27 16:50:45 2019'
注意strftime中的时间格式表达式不支持中文。如果想用中文表示时间,需要用format()方法。
time.strftime("%Y{}%m{}%d{} %H:%M:%S ",t).format('年','月','日')
time.strptime(string,format) 将时间字符串转换为时间类型
t = time.strptime("2019年12月10日",'%Y年%m月%d日')
time.struct_time(tm_year=2019, tm_mon=12, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=344, tm_isdst=-1)
time.struct_time()
time.gmtime()、time.localtime、time.strptime() 返回的时间格式,包含了9个元素的元组
time.sleep(secs)
程序中断执行secs秒
datetime模块
date模块
创建一个date实例
datetime.date(year,month,day)
创建一个date实例。其中年受到datetime.MAXYEAR和datetime.MINYEAR限制
date类方法
date.today() 返回当前的本地时间
date.fromtimestamp(timestamp) 1970.1.1+时间戳后的时间,timestamp参数不可省略
date.fromisoformat(date_string) 将日期字符串变为date时间类型。
时间字符串必须遵守 YYYY-MM-DD 格式,否则报错。
date类属性
date.min
date.max
date.resolution
date实例属性
d.year
返回年
d.month
d.day
date实例的数学逻辑运算
数学运算
d2-d1
d2+timedelta(days=100)
d2 - timedelta(days=100)
d2+d1 出错!
逻辑运算
d2>d1
date实例方法
d.replace(year=self.year, month=self.month, day=self.day)
d3 = d1.replace(year=2013)
替换date实例的数据,并形成一个新的date实例
d.weekday()
返回当前日期的星期。[0-6],0是周一
d3.weekday()
注意和strftime()表达式中的w进行区别,%w 周日为0,weekday()为6
d.isoweekday() 返回当前日期的星期,【1-7】,7是周日
d.isoformat()
将date实例格式化为标注时间字符串
d.__str__() 也可以
d.strftime(format)
格式化时间,同time.strftime(format,t)
d.__format__(format) 也可以
strftome依然不支持中文,如果想使用,请配合使用format方法
d.ctime() 将日期转换为标准时间
d.timetuple() 将date实例,转换成struct_time()
time模块
创建time实例
t = time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
time类属性
time.min
time.max
time.resolution 最小计量单位
time类方法
注意:datetime中time模块没有获取当前时间的方法
time.fromisoformat(time_string) 将时间字符串转换为time实例
time实例属性
t.hour
t.minute
t.second
t.microsecond
t.tzinfo 时区信息
time实例方法
t.replace(hour=21, minute=34, second=30, microsecond=100000, tzinfo=UTC, * fold=0) 修改t实例数据,并形成一个新的time实例
t.isoformat(timespec='auto') 将time实例转换为iso时间字符串。
timespec精确到那一位
t.__str__() 功能类似,但是没有timespec参数
t.strftime(format) 格式化time实例。其中datetime的time模块标识符要比time模块的标识符丰富
t.utcoffset()
If tzinfo is None, returns None, else returns self.tzinfo.utcoffset(None), and raises an exception if the latter doesn't return None or a timedelta object with magnitude less than one day.
t.dst()
If tzinfo is None, returns None, else returns self.tzinfo.dst(None), and raises an exception if the latter doesn't return None, or a timedelta object with magnitude less than one day
t.tzname()
If tzinfo is None, returns None, else returns self.tzinfo.tzname(None), or raises an exception if the latter doesn't return None or a string object.
datetime模块
创建datetime实例
dt = datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
datetime类方法
dt = datetime.today()
创建本地时间,tzinfo=none
dt = datetime.now(tz=none)
创建包含时区信息的时间,如果不设置,则是本地时间
dt2 = datetime.now(tz=timezone.utc)
dt = datetime.utcnow()
创建当前UTC时间。但是不包含tzinfo,
如果想增加tzinfo信息,可以使用replace方法
dt = datetime.fromtimestamp(timestamp,tz=None)
根据一个时间戳创建一个datetime实例,可以指定tz信息。
dt = datetime.utcformstamp(timestamp)
根据一个时间戳,创建一个UTC时间,但是不包含tz信息
dt = datetime.combine(d.date(), d.time(), d.tzinfo)
将date,time,tzinfo实例合并成一个datetime实例。
dt = datetime.fromisoformat(datetime_string)
根据标准字符串生成一个datetime实例。
dtstring = datetime.isoformat(dt)
将datetime实例转换成为标准时间字符串
dt = datetime.strptime(datetime_string,format)
按照指定的格式,将时间格式字符串转换成datetime实例。
datetime类属性
datetime.min
datetime.max
datetime.resolution
datetime实例属性
dt.year
dt.month
dt.day
dt.hour
dt.minute
dt.second
dt.microsecond
dt.tzinfo
dt.fold
时区调整时使用
datetime实例的运算
dt+timedelta(days=10)
dt - timedelta(days=10) -->dt2
dt2-dt1 -->timedelta()
dt2>dt1 -->True
datetime实例方法
dt.date()
返回一个date对象
dt.time()
返回一个time对象,不包含tzinfo
dt.timetz()
返回一个time对象,包含tzinfo
dt.weekday()
返回dt的星期。
Monday is 0 and Sunday is 6.
dt.isoweekday()
返回dt的星期
Monday is 1 and Sunday is 7
dt.replace(year=2020)
修改当前dt对象的属性,并返回一个新的dt对象
dt.isoformat(sep='T', timespec='auto')
dt.isoformat(sep=" ",timespec='seconds')
'2019-03-28 00:08:09'
sep 时date和time之间的分隔符,默认为T
dt.__str__() 也可以,与dt.isoformat(" ")等同
timesspec
时间显示的方式
dt.strftime(format)
格式化时间
dt.__format__(format) 也可以
dt.timetuple()
根据dt,返回time.struct_time
dt.utctimetuple()
根据dt,返回time_struct_time数据。注意awaretime和navietime的区别。
dt.timestamp()
返回一个时间戳
dt.astimezone(tz=timezone.utc)
修改或添加dt的tzinfo属性。
dt.utcoffset()
dt.dst()
dt.tzname()
timedelta模块
创建timedelta对象(实例)
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
weeks = 2
周数
days = 10
天数
hours = 10
minutes = 30
seconds = 60
milliseconds = 6000
microseconds = 100000
注意
没有年和月(years和months)
但是可以通过算法换算成天
直接保存的 days,seconds,micoseconds
其他也是通过内部换算而来的
timedelta类属性
timedelta.min
timedelta.max
timedelta.resolution
timedelta对象(实例)属性
days
seconds
microseconds
运算
td = td1+td2
几种情况
timedelta(days=1)+timedelta(seconds=60) = timedelta(1, 60)
timedelta(hours=1)+timedelta(seconds=60) = timedelta(0, 3660)
timedelta(weeks=1)+timedelta(seconds=60) = timedelta(7, 60)
timedelta(weeks=1)+timedelta(days=60) = timedelta(67)
weeks会自动换算成days然后执行运算
td = td1-td2
timedelta(days=1)-timedelta(seconds=60) = timedelta(0, 86340)
timedelta(hours=1)-timedelta(seconds=60) = timedelta(0, 3540)
td = td1/td2
如果遇到 timedelta(days=1)/timedelta(seconds=60)的情况,会将timedelta(days=1)换算成timedelta(seconds = 24*60*60)再计算,返回的结果:24*60*60/60
timedelta(hours=1)/timedelta(seconds=60) = 60.0
timedelta(days=10)/timedelta(hours=2) = 120.0
td = td1%td2
timedelta(days=9)%timedelta(seconds=56) = timedelta(0, 40)
取余
td = td1//td2
timedelta(days=9)//timedelta(seconds=56) = 13885
整除
td = td1*td2
不支持
TypeError: unsupported operand type(s) for *: 'datetime.timedelta' and 'datetime.timedelta'
td = td*2
timedelta(days=10)*2 = timedelta(20)
timedelta(seconds=10)*2 = timedelta(0, 20)
td = td/3
timedelta(days=9)/2.5 = timedelta(3, 51840)
timedelta(seconds=9)/2.5 = timedelta(0, 3, 600000)
td = td%3
不支持
ypeError: unsupported operand type(s) for %: 'datetime.timedelta' and 'int'
td = str(td1)
str(timedelta(days=9)) = '9 days, 0:00:00'
td = repr(td)
repr(timedelta(days=9)) = datetime.timedelta(9)
timedelta对象方法
td.total_seconds()
返回当前td对象总秒数,与td/timedelta(seconds=1)相同
tzinfo模块
抽象类,无法创建实例,是timezone的基类。
timezone模块
创建一个timezone对象
bjtime = timezone(timedelta(hours=8),name='beijingtime')
tz对象的方法
tz.utcoffset(dt)
返回与utc之间的时间差,timedelta对象
关于dt参数,如果不带,返回当前dt对象与utc之前的时间差。utc前面时dt对象
dt1.utcoffset()
如果带dt参数,则utcoffset前时timezone对象
bj.utcoffset(dt1)
这个值不会因为dt1的时区不同而改变
tz.tzname(dt)
dt.tzname()
不带参数
在创建timezone实例时,name为指定,tzname返回UTC+08:00
bj.tzname(dt)
带任意datetime对象
tz.fromutc(dt)
dt必须是awaretime,否则报错。
timezone类属性
timezone.utc
创建utc的timezone对象。
使用datetime的tiamezone管理时区,比较麻烦,可以使用另一个python库,pytz,方便管理
了解pytz的timezone方法即可。
要查询常用时区,可以使用pytz.common_timezone查询。
关于timezone的注意事项
各地时间的例子
calendar模块
Calendar类
创建Calendar对象(实例)
cl = calendar.Calendar(firstweekday=0)
firstweekday:选择日历每周起始时间。0是周一,6是周日
calendar实例方法
cl.iterweekdays()
创建一个星期迭代器
cl.itermonthdates(year,month)
创建某一年某一月的日期迭代器。
返回这一个月日期的datetime.date 对象。一个例子
cl.itermonthdays(year,month)
创建某一年某一月的日期迭代器
日期为返回int类型。如果不是当月的日期,显示为0
cl.itermonthdays2(year,month)
同上,返回由(日期,星期)组成的元组
cl.itermonthdays3(year,month)
返回由(年,月,日)组成的元组
cl.itermonthdays4(year,month)
返回由(年,月,日,星期)组成的元组
3.7版本
cl.monthdatescalendar(year,month)
创建一个二维列表,包含一个月的数据,[[第一周的每一天],[第二周的每一天]……]
每一个元素为datetime.date类型
cl.monthdayscalendar(year,month)
创建一个二维列表,包含一个月的数据 ,[[第一周每一天],[第二周的每一天]……]
每个元素为一个int类型,不是这个月的数据,用0 表示。
cl.monthdays2calendar(year,month)
同上
每个元素为一个元组,包含(日期,星期)
cl.yeardatescalendar(year,width=3)
创建一年的日历。创建一个多维列表【根据width设置】
单个元素为一个datetime.date对象。
cl.yeardayscalendar(year,width=3)
同上
单个元素为一个数字
不是本月数据用0表示。
cl.yeardays2calendar(year,width=3)
同上
单个元素为一个元组(日期,星期)
不是本月数据,日期用0表示
TextCalendar类
创建TextCalendar对象
tc = calendar.TextCalendar(firstweekday=0)
TextCalendar对象的实例方法
tc.formatmonth(theyear,themonth,w=0,l=0)
创建一个基于当月的多行文本日历,w代表字符的宽度,l代表字符的行间距。
tc.prmonth(theyear,themonth,w=0,l=0)
直接打印日历字符串
tc.formatyear(theyear,w=2,l=1,c=6,m=3)
创建一年日历字符串,c代表各个月份字串之间的间隔,m代表一行有几个月份。
tc.pryear(theyear,w=2,l=1,c=6,m=3)
直接打印日历字符串。
HTMLCalendar类
创建HTMLCalendar对象
hc = calendar.HTMLCalendar(firstweekday=0)
HTMLCalendar对象的方法
hc.formatmonth(theyear,themonth,withyear=True)
创建2019年3月份的日历。hcm_html = hc.formatmonth(2019,3,withyear=True)
withyear=True 表示月份标题后跟年份
hc.formatyear(theyear,width=3)
创建2019年的日历HTML表格,hcy_html = hc.formatyear(2019,width=1)
hc.formatyearpage(theyear,width=3,css='calendar.css',encoding=None)
os模块
打开文件的操作
open函数
file 文件路径
mode 打开方式
r 只读
w 只写
注意,w模式,文件指针位于文件开头
a 追加
文件指针位于文件末尾。
+
更新磁盘文件(变成了可读可写的状态)要和r,w,a配合使用。
r+ 可以write(),文件指针默认为头部,但是如果在write()前使用read(),指针则为文件末尾,在使用write(),就在文件尾部增加内容了。
w+ 可以使用read(),但是直接使用没有返回值。因为此时指针位于文件末尾
a+ 同 a 也可以使用read()但没有返回值。
b
二进制文件,和r w a
返回值 file object( 文件对象)
文件对象的基类
常用的属性和方法
name
返回文件名
close() 关闭文件对象,释放内存
readline() 根据指针位置,读取整行
readlines() 返回一个列表,从指针处,返回每一行的数据。
writelines(seq) 向文件中写入一个序列的字符串。
writable() 文件是否支持写模式。
seek(offset[,whence]) 移动指针。
truncate(size=None) 截断文件
文本对象
常用属性和方法
属性:
encoding
errors
name
返回文件名
mode
打开模式
newlines
文件所采用的分隔符
方法
read()
readline()
write()
seek(offset,whence=SEEK_SET)
tell()
open函数的小应用 复制文件
os常用操作
os.getcwd() 获取当前目录
os.chdir(path) 改变当前工作目录
os.listdir(path) 以列表形似返回目录下所有文件和文件夹名称
os.mkdir(path, mode=0o777, *, dir_fd=None) 创建一个新文件夹,如果文件夹存在,则会抛出异常。
os.makedirs(name, mode=0o777, exist_ok=False) 创建一个多级目录
os.remove(path, *, dir_fd=None) 删除一个文件。
os.removedirs(path) 同makedirs,用递归的方式删除文件夹
os.rmdir(path) 删除一个空目录
os.rename(src, dst) 重命名一个目录或者文件。
os.renames(old,new)
与rename不一样,renames 可以跨目录操作。
os.walk(top, topdown=True, onerror=None, followlinks=False)
这是一个有意思的功能,遍历文件夹下所有的文件,并返回一个生成器
topdown 反映的是游走的顺序,如果是True 自上而下遍历,False自下而上遍历。
生成器的元素是一个元组(路径,[子文件夹],[文件])
第一个应用:返回一个文件夹下所有文件
第二个应用:删除文件夹下所有的空文件夹
第三个应用:寻找文件夹下特定格式的文件。
os.stat(path) 返回文件的状态
os.path模块
关于路径的
os.path.abspath(path) 返回绝对路径
os.path.basename(path) 返回文件名
os.path.dirname(path) 返回path的路径
os.path.split(path) 把路径划分为dirname和basename的元组。即路径名和文件名的元组。
os.path.commonprefix(list) path列表中等级最高的目录。
判断的
os.path.isfile(path) 是否为文件
os.path.isdir(path) 是否为文件夹
os.path.exist(path) 是否存在
os.path.isabs(path) 是否为绝对路径
os.path.islink(path)
路径拆分
os.path.split(path) 分割文件名
os.path.splitext(path) 分割扩展名。
os.path.splitdrive(path) 分割盘符。
路径链接
os.path.join(path1[,path2,...]) 路径拼接
文件属性
os.path.getsize(path) 返回文件大小
os.path.getatime(path) 返回最近访问时间,时间戳
os.path.getmtime(path) 返回最近修改时间
os.path.getctime(path) 返回创建时间
shutil模块
shutil.copyfileobj(rst,dst,length = 16*1024)
shutil.copyfile(src,dst) 复制文件内容,到另一个文件。注意!
shutil.copy(src,dst)
复制文件到另一个文件或文件夹。同时复制文件的内容以及权限。【文件的创建时间为当前时间。】
shutil.copy2(src,dst)
复制文件到另一个文件或文件夹,同时复制文件的内容以及文件的所有状态信息。【文件的创建时间和源文件一样】
shutil.copytree(src,dst) 复制一个文件夹所有内容(包括子文件夹)到另一个文件夹。如果目标文件夹不存在则会创建一个。
shutil.rmtree(path)
删除整个目录
shutil.move(src, dst, copy_function=copy2) 移动文件或文件夹,到另一个文件夹
Python数据类型的操作
数值 int float complex
常用运算符
% 取余
5%2 =1
// 整除
5//2 = 2
复合运算符
+=
x += 1
x = x+1
-=
*=
/=
%=
x %=2
x = x % 2
//=
x//=2
x = x//2
比较运算符
==
>=
<=
!=
>
<
类型转换
float()
转换为浮点型
int()
转换为整形
str()
转换为字符串
eval(expression[, globals[, locals]])
执行字符串表达式
x=1 eval('x+1') >>2
数学运算
内建函数的数学运算
abs()
取绝对值
max()
取最大数
min()
取最小数
round(number[, ndigits])
四舍五入,ndigits表示保留几位有效数字
round(3.134455,3) --> 3.134
关于浮点数的不确定尾数
0.1+0.2 = 0.30000000000000004
pow(x,y)
x的y次幂
pow(2,10)
1024
math模块
math.ceil(x)
向上取整
math.ceil(3.14) -->4
math.floor(x)
向下取整
math.floor(3.14) -->3
math.sqrt(x)
取平方根
math.log(x)
取对数
更多数学函数,参照官方文档
random模块
random.seed(a=None,)
初始化随机数生成器。
random.random()
返回0-1的随机小数
0.24999667668640035
random.randrange(start, stop[, step])
返回随机选择一个某个范围内的range序列的元素
s = random.randrange(2,100,2)
random.uniform(a, b)
返回a-b的随机数
random.uniform(1,10)
4.43445387327206
random.choice(seq)
在一个非空序列中,随机挑选一个元素
random.choice(range(100))
random.randint(a,b)
返回a到b任意一个整数
random.randint(1,10)
3
random.shuffle(x[,random])
将原序列打乱,修改原序列,不生成新序列
random.shuffle(s)
其他高级随机函数,数理统计使用
random.triangular(low, high, mode)
random.betavariate(alpha, beta)
Beta 分布。 参数的条件是 alpha > 0 和 beta > 0。 返回值的范围介于 0 和 1 之间。
random.expovariate(lambd)
指数分布。 lambd 是 1.0 除以所需的平均值,它应该是非零的。 (该参数本应命名为 “lambda” ,但这是 Python 中的保留字。)如果 lambd 为正,则返回值的范围为 0 到正无穷大;如果 lambd 为负,则返回值从负无穷大到 0
random.gammavariate(alpha, beta)
Gamma 分布
字符串 str
r 原始字符
path = r"c:\table\new"
转义字符
\t
制表符
\n
换行符
\r
回车
\\
返回\本身
拼接
str1+str2
切片
str = “零一二三四五六七八九”
str[1] = "零"
str[-1] = "九"
str[0:2] = "零一"
切片原则:左开右闭
str[-1:] = "九"
和str[9:]相同
取最后一个元素,都用发着数的切片操作,不需要知道字符串的长度,直接-1:就可以了
str[-2:] = "八九"
取最后两个数
str[-10:-3] = "零一二三四五六"
str[::-1] = "九八七六五四三二一零"
-1是步长
str[1::2] ='一三五七九'
2是步长
格式化字符串
% 格式化字符串
str = "这是第%d题,题目是%s"%(10,"hello world")
%[(name)][flags][width].[precision]typecode
(name)指定的key
"%(name)s:欢迎您,您前面有%(line)d位在排队"%{'name':"david",'line':10}
[flags]
+ 在数字左边加正号,负数加负号
"%+d"%(-10) -->-10
"%+d"%(10) --> +10
- 在数字左边,正数不加+ 负数加符号
"%-d"%(10) --> 10
0 空白位用0填充,正数不加+,负数加负号,关于空白位,要配合width
"数字:%02d"%(9) -->09
0表示填充
2 表示宽度,宽度不足用0补
空格 正数前加空格,负数前加负号
width 宽度
"宽度:%10s"%("加")
宽度: 加
.precision 小数点几位,【和f配合使用】
"%.2f"%(3.1234) --> 3.12
typecode
常用格式符
%s
字符串
%d
整形
%f
浮点型
%e 和 %E
科学计数法
%g 和 %G
科学计数法,超过6位科学计数,6位以下正常计数
%%
百分号
format 格式化字符串
"{}你好,您前面还有{}位客户".format("david",10)
"{name}你好,您前面有{line}位顾客".format(name='david',line=10)
{}的格式::[[fill]align][sign][#][0][width][,][.precision][type]
[[fill]align] 对齐和填充
fill 空白处填充的字符,和lalign连用,向左向右或居中填充指定字符
“{:+>3d}”.format(9) --> ++9
align 对齐和width搭配使用
> 左对齐
"{:>2d}".format(9)
< 右对齐
“{:+<3d}”.format(9) --> 9++
^ 居中对齐
"{:+^5d}".format(9) -->++9++
[sign] 有无符号的数字
+
正数加+,负数加-
"{:+d}".format(9) --> +9
-
正数不变,负数加-
"{:-d}".format(9) -->9
空格
正数加空格,负数加-
"{: d}".format(-9) -->-9
[#] 【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
[0]补零,与width搭配使用,数据类型为整形,浮点字符串不起作用
[width]位数
[.precision]小数后几位,与f e E g G %联用
E和G的计数法默认位数为六位,超过6为就用科学计数法,但是如果限定了位数,则以位数为准
, 千位逗号显示
'{:,d}'.format(9000) -->9,000
[type]
s 字符串 默认
d 十进制整数
f 浮点数
e和E 科学计数
g 和G 科学计数,六位以下正常计数,以上科学计数
% 百分数计数
b 二进制
o 八进制
x和X 十六进制
c Unicode字符
查找
str.find(sub[,start[,end]])
find和rfind,查找字符串,如果找到返回匹配字符串(sub)所在位置,找到即止【第一个匹配的字符串位置】,找不到返回-1
str.index(sub[,start[,end]])
index和rindex,同find,不同的是,找不出抛出异常。
统计
str.count(sub[,start[,end]])
查找查询字符串出现的次数
填充
str.ljust(width[,fillchar])
ljust和rjust,width字符宽度,fillchar填充的字符,默认为空格,ljust左填充,rjust右填充
删除
str.strip([chars])
去除指定字符,默认为空格
lstrip([chars]) 从左开始,找到移出
rstrip([chars]) 从右开始,找到移出
替换
str.replace(old, new[, count])
查找字符串,并将字符串中的字符(old)替换成新字符(new),count是替换的次数,默认全部替换
分割
str.split(sep=None, maxsplit=-1)
根据指定字符串(sep)分割字符串,并生成一个列表。默认空格,maxsplit默认最大分割数,默认-1 全部分割
str.splitlines([keepends])
根据换行符分割字符串。\n 换行;\r 回车 keepends是否保留结尾换行符,True保留,False不保留,默认不保留
str.partition(sep)
根据sep将字符串分成一个三个元素的元组,(“左边”,“sep”,“右边”)
str.rpartition(sep) 从右只至左
字母格式
str.capitalize()
将一段字符的首字母大写
str.title()
将一段字符中所有单词的首字母大写
str.upper()
将所有字母变为大写
str.lower()
将所有字母变为小写
连接
str.join(iterable)
将一个可迭代对象按照str连接,返回一个新字符串
判断
is判断
isalpha()
是否全部是字母,全是字母True,否则False
isnumric()
是否是数字
isdecimal()
如果字符串是否只包含十进制字符返回True
isalnum()
时候是字母和数字
isspace()
是否右空格
前置字符后置字符判断
str.startswith(prefix[, start[, end]])
是否以前缀开始
str.endswith(suffix[, start[, end]])
列表 list
定义
有序可变的数据集合
定义方法
[1,2,3,'4']
列表生成式:range(start, stop[, step])
list(range(10))
list(range(1,10,2))
list(range(0,-10,-2))
列表推导式:[表达式 for in iterable if 条件表达式]
[x*2 for x in range(10) if x%2 == 0]
[i*2 for i in ['a',2,3,'5'] ]
[i*2 for i in ['a',2,3,'5'] if type(i)== int ]
list() or list(iterable)
操作
增加
list.append(x)
向列表最后追加一个元素,会改变原列表数据
list.insert(index,x)
在列表指定位置(index,位置索引)追加一个元素,同样会改变原列表数据
list.extend(iterable)
将一个可迭代的列表追加到列表,改变原列表数据
*
按照*扩展列表,['a','b']*2 --> ['a', 'b', 'a', 'b']
+
两个列表相加 ['a','b']+['c','d'] --> ['a','b','c','d']
注意,相加的必须也是列表,如果不是可以使用list(iterable)变为列表再相加
删除
del list[index]
删除指定元素,指定索引范围的元素[1:5],或者删除整个列表
指定元素 del List[1]
指定范围:del List[1:10]
整个列表:del List
list.pop(index=-1)
list.pop() 默认删除最后一个元素,并返回删除的元素,同时改变原来列表的数据
list.pop(5) 删除指定位置元素,并返回删除的元素,同时改变原来列表数据
index越界,报错IndexError: pop index out of range
一次只删除一个内容
list.remove(object)
删除列表内容,存在删除,改变原列表,不存在报错,多个删除左边一个
删除的内容存在
删除的内容不存在
删除的内容有多个
一次只删除一个内容,不可同时删除多个
list.clear()
删除列表所有元素
修改
list[index] = 'xxx'
查询
索引查询: list[1:10:1]
同字符串的切片操作
list.index(x[, i[, j]])
x在列表中的位置,在i前j后
list.count(x)
元素出现的次数
遍历
for i in list:
for index in range(len(list)):
其他操作
排序
内建 sorted函数
sorted(itrearble, key=None, reverse=False)
iterable 可迭代的对象
key 排序关键词,传入一个函数,如str.lower
reverse=False 正序,True 倒序
形成一个新的列表
list.sort()方法
list.sort( key=None, reverse=False)
key同sorted函数
reverse同sorted
改变原来列表的排序
随机排序
randmon模块 random.shuffle(x, random=None)方法,改变原来列表
反转
list.reverse()
list[::-1]
in 和 not in
比较
备查:可变序列的常用操作方法
元组 tuples
定义
Python 的元组与列表类似,不同之处在于元组的元素不能修改。Tuples are immutable sequences(不可变序列)
定义方法
操作方法
仅支持序列的常用操作方法,不支持诸如append,insert等可变序列的操作方法
索引查询
t[1]
t[1:2]
t[1:10:2]
查找
max(t)和min(t)
注意,元组必须时同一类型数据才可以进行比较
t.index(x[,i[,j]])
统计
t.count(x)
返回元组某个数据的个数
len(t)
返回元组个数
字典 dict
定义
无序的, 可变的键值对集合,key不重复,value值和类型都随意
定义方法
操作方法
新增和修改
dict['key'] = value
key不存在,新增,key存在修改
key不可修改,也不可重复
dict.update(dict2)
将dict2内容复制至dict,键存在覆盖,键不存在新建
删除
del dict['key']
key存在删除,不存在报错 KeyError: 'age'
dict.pop[key[,default]]
删除指定key内容,并返回删除的内容,如果key不存在
指定default ,返回default
未指定default,抛出key异常。
dict.popitem()
删除最后一个键值对,并以元组形式返回这个删除的键值对,改变原有字典
关于字典的LIFO order last in first out
dict.clear()
清除字典内容
查询
dict['key']
如果key不存在,则会抛出 KeyError 错误
dict.get(key[, default])
如果key不存在,返回default,如果没有制定default,返回none
dict.items()
返回字典的键值对,对dictview对象
关于dictview的官方文档
例子
dict.keys()
返回字典的键
dict.values()
返回字典的值
iter(dict)
返回一个迭代器,默认是key,如果键值对 iter(dict.items())
for in
for values in dict.values()
for key in dict.keys():
for k,v in dict.items():
判断 x in dictview
key in dict.keys()
values in dict.values()
x in dict
默认是key
集合 set
概述
无序的, 不可随机访问的, 不可重复的元素集合
可对其进行交、并、差、补等逻辑运算
set支持和不支持的操作
支持的操作:for in ,len,in,sorted
不支持的操作:索引s[1],切片等序列操作
定义
可变集合 set
s = {1,2,3,4}
s = set(iterable)
集合推导式
s = set(x for x in range(20) if x%2==0)
s = {x for x in range(10)}
注意:s={} 创建的是空字典,不是空集合
空集合的创建 s = set()
注意:集合的元素必须是可哈希的值,否则会报错
不可变集合 forzenset
s = frozenset(iterable)
推导式创建
s = frozenset(x for x in range(100) if x%2==0 )
基本操作
可变集合的操作
增加
s.add(element)
删除
s.remove(element)
删除某个元素,元素不存在报错
s.discard(element)
删除某个元素,元素不存在时,不报错
s.pop()
删除集合内任意一条元素,并返回该删除的元素,当集合为空报错
s.clear()
清空集合
修改
不支持修改操作,因为储存的元素为不可变类型,可哈希的值
查询
不支持索引查询,但可以for in 遍历查询,也可以创建迭代器iter(s)查询
不可变集合forzenset的操作
创建后,不支持所有编辑操作
支持查询 for in 和创建迭代器查询iter(s)
集合操作(交集、并集、差集等操作)
交集
& 集合之间的交集
返回一个两个集合共有元素的新集合
s.intersection(iterable) 集合与任意可迭代对象的并集
返回一个两个集合共有元素的新集合
s.intersection_update(iterable) 集合与任意可迭代对象的并集,并更新原集合为并集的内容
&=
更新原集合,不生成新集合
并集
| 集合之间的并集
返回一个新集合
s.union(iterable) 集合与任意一个可迭代对象之间的交集
返回一个新集合
s.update(iterable) 集合与任意一个可迭代对象之间的并集,并将结果更新至原集合
不返回新的集合
|=
更新原集合,不生成新集合
差集
- 集合之间的差集
返回当前集合与比较集合之间不一样的元素
s.difference(iterable) 当前集合与任意一个可迭代对象的差集
返回当前集合与比较集合之间不一样的元素
s.difference_update(iterable) 当前集合与任意一个可迭代对象的差集,并更新当前集合为差集的结果。
不返回新的集合
-=
更新原集合,不生成新集合
去除交集
^ 并集结果中去除集合相交的元素
形成一个新的集合
s.symmetric_diffrence(iterable)
s.symmetric_difference_update(iterable)
^=
更新原集合,不生成新集合
集合判断
s.isdisjoint(iterable)
Return True if the set has no elements in common with other. Sets are disjoint if and only if their intersection is the empty set.
s.issubset(iterable)
当前集合是否是任意可迭代对象的子集。
s.issuperset(iterable)
任意可迭代对象是否是当前对象的子集
与数据类型有关的各种内置函数
enumerate(iterable,start=0) 枚举
返回一个枚举对象,将一个可迭代的数据,将可迭代对象中的每个元素转换成带有数字索引的元组。
filter(function,iterable) 过滤
遍历可迭代元素的每个元素,根据函数判断,符合函数指定的规则返回True,不符合返回False,最终返回元素为True的列表。
isinstance('a',str) 判断数据类型
经典用法是,判断数据类型
实现原理是,判断某个对象,是不是某个类的实例。在python中万物皆对象,所以可以用来判断数据类型
zip(iter1,iter2……) 聚合多个迭代器的元素
根据最短的可迭代元素,返回如上的结果。
算法原理:将所有可迭代元素创建为迭代器
逐次分别使用next遍历迭代器,并将遍历结果存入容器
当触发停止信号时,停止迭代,返回容器
当出现空值时,触发停止信号,停止循环,返回之前结果
结果
依次遍历所有列表,根据最短的列表,返回的格式
第一行 所有列表的 第一个元素
第二行 所有列表的第二个元素
第三行 所有列表的第三个元素
map(function,iterable) 对可迭代对象中每个元素进行处理
例如:对列表a中所有元素平方后返回。
Python函数
函数基础
定义函数
函数的参数
形参和实参
定义函数的参数为形参,使用函数时为实参
定义一个函数【形参】
使用一个函数【实参】
位置参数和关键字参数,和默认值
位置参数:使用函数时,传入参数可以根据参数定义位置,进行传递。
关键字参数:调用函数时,传递参数也可以使用func(a=10,b=10,c=20)的关键字形式传递。
关键字参数,位置可以随意。
调用函数时,位置参数和关键字参数方式只能选一个
默认值:定义函数时,可以为某个参数指定默认值,调用函数时,如果不传递该参数,函数并不会报错,而是以默认值运行。
定参和不定参
定参
定义函数时,定义了确定的参数,def func(a,b)称之为定参。
不定参
定义函数时,并不定义确定的参数,在参数名前,加 * 和 ** 就可以使用任意个数的参数了。约定俗成的用法 def func(*args,**kwargs)
装包和解包
当使用不定参时,*args,**kwargs 就涉及到装包和解包操作了。
装包
args
将所有参数装包成元组,函数体内不涉及函数调用,可以使用for in 使用数据。
kwargs
将所有参数装包成字典。在函数体内使用字典数据,如果涉及到函数调用,则要用到解包操作。
解包
*args
将元组解包成函数调用的数据。解包操作一般在函数体内调用其他函数使用。
**kwargs
将字典数据解包成函数调用的数据。
函数进阶
偏函数
定义和应用场景
重新定义一个函数
使用functools模块的partial函数
高阶函数
定义和应用场景
一个例子
匿名函数
lambda 表达式
闭包
定义和应用场景
一个案例
闭包的方法
partial方法。
注意事项
nolocal 变量
外层函数的变量为可变量时,需要注意。
装饰器
定义和应用场景
解决思路:闭包
语法糖:在定义函数前使用@装饰器函数。
情况一:定义的函数,没有参数,没有返回值。
情况二:定义的函数,有参数,没有返回值
情况三:定义的函数,有参数,有返回值
情况四:装饰器有参数
生成器
定义和场景
定义的两种方式
g = (x for x in range(10000000)) 生成器表达式
yield 语句
生成器的常用方法
内置函数 next(iterator)
g.__next__() 生成器方法
使用next语句到最后一个yield时,抛出StopIteration异常。
g.send(value) 方法
g.close() 停止生成器
生成器的注意事项
生成器只能用一次。
获取数据的两种方法
for in
next() 和__next__()
不支持切片操作。
遇到return语句,生成器立即终止,抛出StopIteration异常,同时返回return的值。
递归函数
定义和场景
注意事项:定义递归函数时,一定要设计回归条件,否则会进入死循环,最终抛出maximum recursion depth exceeded 异常。
应用案例
使用递归函数遍历文件夹
Python 面向对象
对象的概念
对象描述的是一个具体事物,它包含了两个层面,属性和行为
属性
方法
在Python中万物皆对象。
其实面向过程和面向对象都是解决问题的一种思路。
面向过程的思路是将过程进行分解。
面向对象的思路,将对执行任务的对象进行分解。实际上是对面向过程的封装。
类
类和对象的关系。
类和对象,有点类似配方和产品的关系,产品根据配方的定义进行生产,而产品就是对象,配方则是类。
所以类也被称之为某个具体对象的抽象。
类的作用
根据类的定义,产生具体的对象。
类的构成
名称
属性
方法
对象和类的关系
对象→抽象→类→实例化→对象
定义一个类
类的底层操作
Student.__name__
返回类名。
s.__class__
实例化对象后,返回引用的类。
对象和类的属性
对象的属性
对象属性的操作
增加
通过赋值动态添加
s1.height = 180
通过构造函数创建
修改
通过 s.age = 12 进行修改
查询
直接 s.age 可查询
删除
del s.age 删除属性
类属性
类属性操作【注意事项,通过类可以增删改查操作,但是不能通过对象改变类的属性。】
属性的存储原理
__dict__属性
对象的__dict__属性是可读可写的。
类的__dict__属性是只读的。
属性查询修改操作的注意事项
属性查询:优先从自己对象中寻找,如果没有找到,则到创建它的类中寻找。
属性修改:从自己对象中寻找属性,如果有,直接修改,如果没有,并不会到创建它的类中寻找,而是创建一个新的属性。这里需要注意。
通过类限定对象只能添加限定的属性
__slots__
对象和类的方法
三种不同的方法的创建
实例方法
实例方法的创建
必须要有一个参数 self,且放在第一个。
标准调用:通过实例调用实例方法,调用时self参数编译器会自动填进去,不需要传入。
间接调用:通过类名进行调用,此时self需传值,且self没意义。
类方法
类方法的创建 @classmethod
类方法的调用,可以通过类直接调用,也可以通过实例进行调用
案例
静态方法
静态方法的创建 @staticmethod
静态方法的调用,可以通过类直接调用,也可以通过实例进行调用。
静态方法小案例,计算三角形面积。
三种方法如何使用类属性和实例属性
实例方法:可以self访问实例属性和类属性。
类方法:可以通过cls访问类属性,但不能访问实例属性
静态方法:不可以通过self、cls等关键字访问实例属性和类属性
元类 type
创建类对象的类。
type的作用
判断数据的类型。type("a") >>>class 'str'
创建一个类。
type(name, bases, dict)
name:类名称
bases:继承的类
dict:属性和方法字典。
X = type("X",(),{'age':19,'run':lambda self:print(self)})
__metaclass__
指定元类
创建类的帮助文档
在类和方法下使用 ''' '''
将所有帮助文档,汇总,可以使用 pydoc 模块
在 cmd 模式下, cd 项目所在目录
使用命令:python -m pydoc -b 会在浏览器打开帮助文档
使用命令 Python -m pydoc -w 文件名,生成一个html格式的帮助文档
使用第三方模块
Sphinx
epydoc
doxygen
私有化属性
公有属性
a = 10
访问
类内部访问
子类内部访问
模块内其他位置访问
跨模块访问
跨模块
from 模块名 import *
调用 a
受保护的属性 _a
_a = 10
访问
类内部访问
子类内部访问
模块内其他位置访问
可以访问,但不推荐
跨模块访问
import 模块名
调用 模块名._a
可以访问,但不推荐
from 模块名 import *
不能调用。
私有属性 __a
__a = 10
访问
只能在类内部访问
子类和实例都不能直接访问
模块其他位置也不能直接访问
跨模块
import 模块名
调用 模块名.__a
可以访问,但不推荐
from 模块名 import *
不能调用。
私有属性的实现机制
名字重整机制
_类名__a
私有属性的应用场景
数据保护
数据过滤
案例
只读属性
如果你看到
a_
防止与系统保留名称重名,可以在后面加一个下划线 _
__a__
系统内置的命名
如何设置只读属性
私有属性和只读属性是两个概念,私有属性只是限定了变量的作用域。只读属性限定了变量的功能,只可以读取数据,不能写入数据。
如何实现
方案一
使用property装饰器,
补充:经典类和新式类
Python 2 版本 默认不继承 object
通过 类名.__bases__
Python 3 默认继承 object
在经典类中,property只能读取属性,并不能设置和删除属性。
property用法
使用property函数:property(fget=None, fset=None, fdel=None, doc=None)
使用property装饰器
获取私有属性的值 @property
设置私有属性的值 @私有变量名.setter
删除私有属性的值 @私有变量名.deleter
方案二:使用__getattr__(self,name) 、__setattr__(self,key,value) 、__delattr__(self,name) 函数
__getattr__(self,name)注意事项:
如果属性存在,且该属性不是私有属性时,调用 实例.属性,不会调用getatrr方法。
但是在设计 getattr() 函数时,需要考虑,当调用的对象属性不存在时,需要抛出 AttributeError 异常。否则函数返回为None,会引起误解。
方案二的另一个应用。当某些数据初始化后,就不能再次修改。
这是一个比较巧妙的方法,不需要设置私有属性,通过getattr来控制属性的赋值操作,以实现可读的效果。
私有化方法
同私有化属性,只能在定义的类范围内使用,子类,实例,模块内,均不能调用。
_run()
受保护的方法,使用同受保护的属性
__run
私有化方法。
内置属性和内置方法
内置属性
类属性
__dict__
__bases__返回该类继承的所有父类的元祖
__doc__ 类的文档 """ """中的内容
__name__ 获取类的名称
__module__ 获取类所在模块
实例属性
__dict__
__class__ 实例对应的类。
常用的内置方法
信息格式化方法
object.__str__(self)
当调用print函数时,输入打印内容,注意这个函数的返回值,必须是字符串类型。且正常语言。
object.__repr__(self)
返回的也是字符串,相比较str,repr返回的字符串要反应数据特征,是程序语言
如果没有定义__str__ 使用print函数时,也会调用repr方法。
其实
调用操作
object.__call__(self)
使实例具有调用功能,并且可以通过call调用,向实例传入参数,完成一定的功能。
一个简单案例:实现画笔(钢笔,铅笔)和颜色(rgb)调用问题。
索引操作和切片操作
object.__setitem__(self,key,value)
object.__getitem__(self,item)
object.__delitem__(self,item)
与 getattr,setattr,delattr的区别。
getattr 使用 实例.属性 来自动触发
getitem使用 实例['值'] 来自动触发
getitem也会触发切片操作。
此时的key 变成了 [key.start:key.stop:key.step]
比较操作
__lt__
小于 less than
x<y 时会触发
__le__
小于等于 less than or equal to
x <= y 触发
__gt__
大于 greater than
x>y 触发
__ge__
大于等于 greater than or equal to
x >= y 触发
__eq__
等于 equal
x == y 触发
__ne__
不等于 not equal
x != y 触发
遍历操作
可以通过 __getitem__(self,item) 方法
注意:一定要设置终止遍历的条件,否则会出现死循环。
如果想要实例即支持for in 遍历,也要支持对象['值']的操作,建议,遍历的部分,可以用 iter 方法和 next 方法。
__iter__和 __next__
__iter__(self)
for in 操作的时候,会首次触发。
注意:这个函数的返回值,必须是一个迭代器类型。
如果返回的是一个可迭代的对象,可以使用iter函数将可迭代对象包装成迭代器。
如果一个对象中同时含有 __iter__ 和__next__方法,那这个对象就是一个迭代器。
__next__(self)
当使用for in的时候,通过__next__逐一访问容器中元素。
也可以使用next()函数和对象.__next__()方法,访问元素,但使用next函数并不会触发iter。
如何判定一个对象是否是迭代器。
关于collections.abc库
Iterable
如果有__iter__方法,返回True
其实使用 __getitem__方法也可以迭代。但是Iterable 无法检测,返回false
iter(objec) 函数则可以,如果可迭代,不报错,不可迭代,报错。
Iterator
同时有__iter__和__next__方法的对象,就是一个迭代器。
使用
isinstance(object,Iterable)
isinstance(object,Iterator)
描述器
描述器的工作原理
定义一个描述器的类class Description:
并定义__get__、__set__、__delete__方法
如果只定义了 __get__方法 称之为 no-data description 非资料描述器,访问优先级低于 __dict__
如果遇到同名属性,则优先在__dict__中寻找,没有才去找描述器。
同时定义了__get__、__set__方法,称之为 data decription 资料描述器,访问优先级高于 __dict__
如果遇到同名属性,则优先在描述器中寻找,没有,再去dict中寻找。
在另一个类A的定义中实例化一个描述器并赋值给一个类变量 a = Description()
实例化这个新定义的类,a = A() 后
可以通过实例a.a 触发描述器的set、get、delete方法。
a.a = 10
会触发描述器的 set 方法
print(a.a)
会触发描述器的get方法
delete a.a
会触发描述器的delete方法
通过类A.a 只能触发__get__方法。需要注意。
当重新定义 __getattribute__(self,item) 方法时,描述器的get方法会被拦截,描述器就不起作用了。
如何用描述器,操作类属性和实例属性。
操作类属性
def __get__(self, instance, owner):
操作实例属性
def __get__(self, instance, owner):
用描述器实现Property装饰器的效果
通过类定义装饰器
简单装饰器
带参数的装饰器
对象的生命周期
对象生命周期相关的三个方法
__new__
当一个对象被创建时,会先执行__new__方法,其次再执行__init__方法。
如果__new__函数没有返回这个类的实例,否则,__init__不会运行。
子主题
__init__
当实例被创建后的一些初始化赋值操作。
__del__
当实例被删除后,执行的操作。
一个小案例,计算某个类一共实例化了多少个对象。
Python的内存管理思路
当数据被创建时
Python 万物皆对象
当一个对象被创建时,会被分配一块内存存储该对象数据,并返回一个内存id
如果遇到相同的字符串,数字,布尔值等小数据量且不能发生改变的数据,Python会分配同一个内存地址存储数据,提高运行效率。
容器类对象,储存其他对象时,只会储存对象的引用,并非对象数据本身。
当数据被回收时(垃圾回收机制)
引用计数器
记录数据对象被应用次数
增加一个引用 +1
删除一个引用 -1
sys.getrefcount(obj)
sys模块的getrefcount(obj)可以获取对象被引用的次数。
增加的场景
对象创建时 +1
对象被引用 p1 = p0 +1
对象作为函数的参数 +2
容器对象内的一个对象 +1
减少的场景
显示删除对象的引用 -1
离开作用域 自动减少
存储该对象的容器被删除 -1
对象的三大特性
封装
继承
object和type的区别
type表示的是对象是由某个类实例化的。是实例化的关系
查找某个实例的类。对象.__class__
object表示的是某个类继承了那个父类。是继承的关系
查找某个类的父类 __bases__
关于继承的MRO算法。
2.2版本以前,深度优先原则
但是如果遇到菱形继承的情况,会出现异常
2.2 版本,当出现了新式类后,分为两种算法
经典类依然是深度优先
新式类,先按照深度优先算法,当遇到菱形继承的时候,会出现相同的继承父类,相同的父类,选取最上面的父类,MRO下方的删除。
点看查看示意图
示意图
压栈操作
这种算法,对于有问题的继承,会无法识别。
2.3版本
经典类,深度优先算法
新式类
C3算法,merge函数。
Python3以后
都使用 C3算法
点击打开图片查看具体算法。
继承可以实现资源的共用
注意 __age 父类的私有属性,子类不会显示的继承
遇到同名属性和方法的 会重写
如果在MRO链条上,出现有相同的方法时,链条前的属性和方法会覆盖链条后的。
例如 在这个mro链条上 [A,B,C,D,E,F,O] 如果BCDEF 都有一个age属性,A.age 时,会优先使用B上的age属性值。
资源的累加。
super函数的用法
super函数的作用,可以找到mro链条上类,最常用的方法,调用父类的方法,实现方法重写,实现功能和资源的累加。
特别是调用父类的方法时,不需要写入父类的类名,在需要重写的方法中,直接调用super().父类的同名方法。就可以实现。
使用super的另一个好处,处理菱形继承关系时,使用super 方法,不会出现,某些方法被多次重写的情况。
直接采用父类名.方法 重写方法存在的问题
使用super方法,可以有效避免。
在Python3版本以后,可以直接用super(参数1,参数2)方法
super函数,将根据参数2为基准,返回参数2的mro链。mro列表
再根据参数1(指定的类)在mro链中位置,返回这个mro链条中下一个类。
调用这个类的方法,以实现方法重写
运行逻辑
一个案例,带有log功能的字典类
抽象基类
多态
关注鸭子类型的概念
使用Python变量,并不需要声明对象是什么类型,而是Python会检测声明对象方法,通过方法,来自动判定该对象属于哪一种类型。
a = 1
int
a = 1.0
float
Python异常
常见异常
除零异常
名称异常
NameError
name 'a' is not defined
类型异常
TypeError
1 - '1'
unsupported operand type(s) for -: 'int' and 'str
索引异常
IndexError
s = '123'
s[5]
s[5]
IndexError: string index out of range
值异常
ValueError
int("a")
ValueError: invalid literal for int() with base 10: 'a'
键异常
KeyError
d = {'a':'a'}
d['b']
d['b']
KeyError: 'b'
属性异常
AttributeError
d = "s"
d.s
d.s
AttributeError: 'str' object has no attribute 's'
迭代器异常
StopIteration
s = iter([1,2])
s.__next__()
s.__next__()
s.__next__()
s.__next__()
s.__next__()
s.__next__()
StopIteration
所有的异常都继承自Exception类。Exception类继承BaseException类。
处理异常
try 语句
try:
执行可能会存在异常的语句
except 异常类型:
如果出现某种异常后处理的语句,比如写一个记录异常的日志文件中。
except 异常类型:
如果出现的异常与指定的异常类型不匹配时,到时在代码运行结束时,也会抛出异常。且except后的代码块也不会执行。
可以有多个except语句
注意:检测机制是从上到下检测,且只检测一次,一旦遇到异常就执行except语句,后面的错误就不会被检测了。
except (异常类型1,异常类型2):
多个种类异常,可以输入一个元组。
except 异常类型 as e:
可以把抛出异常描述,赋值给一个变量。
except Exception:
如果不确定是何种异常,且所有异常的处理语句是一样的,就可以使用Exception 当然可以用 as
不写异常类型,也可以,但是尽量不要用
else:
当try语句,没有异常时,执行else里的语句。
注意:如果出现异常,这里语句就不会被执行了。
finally:
不管有没有异常都会执行的语句。
with 语句
with content_expression as 别名:
执行的逻辑语句
执行的逻辑语句
with语句一般用在读取文件的操作。content_expression语句,须返回一个上下文管理器对象。
这个对象,一般有__enter__()和__exit__()两个方法。open和close两个方法。
这个语句的作用,不管下方的 执行的逻辑语句 有没有异常,都会在语句结束后执行__exit__() 方法,释放内存。
类似 try finally语句。
注意,with语句只是关心语句执行后的close操作,但是并不会处理异常,所以有异常照样会抛出异常。
如果想处理异常,可以自定义上下下文管理器。
自定义上下文管理器。
contextlib 模块。
@contextlib.contextmanager
将一个生成器函数,转换成上下文管理器。
自定义的错误处理语句
closing方法
如果一个类定义了close方法,那么可以使用closing方法,将这个类的实例,装饰成一个上下文管理器。当使用这个实例方法时,可以使用with语句。结束后,释放这个对象的资源。
with语句的嵌套
with open('a.txt','r') as a,open('b,txt','w') as b:
手动抛出异常
raise 语句
自定义异常
定义一个类必须继承Exception
完整的案例
Python 包和模块
一些基础概念
模块
将一组相关功能的代码写入一个单独的py文件中,需要使用的时候 直接导入相关问文件即可。
包
有点类似文件件,定义了多个模块和子包。
在这个目录下,一定要有一个__init__.py文件,
库
完成一定功能的代码集合
框架
一个架构层面
实现一个开放性功能而设计的具有一定约束性的支撑架构
有多个包和模块构成
包和模块的使用遵循一定的约束性规则
当框架创建好后,直接去使用就可以了。大大提高开发效率。
包和模块的分类
系统内建的包和模块
builtins包,使用不要import导入,系统默认导入。
其他的一些内建包,需要import 导入
但不需要单独pip安装。
这些内建的包和模块只会完成一些基础的功能
第三方包和模块
需要单独pip安装后,才能import导入。
功能比系统内建的包和模块要丰富
自定义包和模块
也可以根据业务逻辑需要,自己定义一些包和模块。
包和模块的创建
模块的创建,直接新建一个py文件即可。
包的创建
创建一个文件夹
定义一个__init__.py文件
当导入包的时候,会自动执行这个文件。
包和模块的导入
import 常规导入
import M
import M1,M2,M3
import M as 别名
from 方式导入
导入模块或者包的部分资源
from datetime import date
导入模式
包-->模块
from 包 import 模块1 as 别名1,模块2 as 别名2
from 包.子包 import 模块1
注意:不要 from 包 import 子包.模块
模块-->资源
from 模块 import 资源 as 别名
可以使用点确定模块的路径。
from datetime.date import today
特例
from 模块 import *
模块里要有一句
__all__ = ['变量名1',‘变量名2’,……]
from 包 import *
在包的__init__.py 文件要有一句
__all__ = ['模块1','模块2',……]
* 代表所有非下划线的资源 _a,__a 不能导入,因为是私有资源。
注意:from 只能看到下一级资源,下下一级的资源看不到。
导入逻辑:
第一次导入
现在模块当下的命名空间中,执行所有代码
创建一个模块对象,并将模块内所有的顶级资源绑定在这个对象上。
在import位置,在import 后面的变量名,将这个模块对象赋值给这个定义的变量名。
第二次导入
只会运行上面的第三步,引用这个模块对象的内存地址。
导入模块的优先级
内置模块 --> 路径列表sys.path
sys.path 返回一个列表
当然可以修改sys.path列表,增加搜索路径。
导入的常见场景
如果遇到模块体积大,且用到次数少的模块,可以在某个命名空间内导入。如函数、类等,只有调用才会导入。
防止导入被覆盖的情况
自定义模块时尽量不要和常用模块和内置模块重名、
循环导入
不要使用
可选导入
包内相互导入
绝对导入
from 包 import 模块
对于自定义的包和模块,如果出现包内调用,可能会存在路径错误,此时最好使用from . import 模块名 来解决可能存在的导入错误。
相对导入,用. 来代表路径
from . import 模块名
当前目录
from .. import 模块名
当前目录的上层目录
第三方包和模块的使用
0 条评论
下一页