Day21:装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,简单来书就是用来修改其他函数的功能的函数
装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象,装饰器的开放封闭原则:
即****对扩展是开放的(任何一个程序都不可能在设计之初就已经设计好了所有的功能并且更新和修改,所以我们必须允许代码扩展,添加新功能),对修改时封闭的(因为我们写的这个函数,可能已经有其他人在使用了,所以如果此时修改的话,就会影响其他已经在使用该函数的用户)
装饰器经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景
装饰器可以用def的形式来定义,分为带参****装饰器****和****不带参****装饰器,不带参的装饰器就是最简单的装饰器
Day22:参数注解
- python是动态语言,变量随时可以被赋值,且能赋值为不同的类型,动态语言很灵活,但是这种特性也是弊端,函数的使用者看到函数的时候,并不知道你的函数的设计,也不知道应该传入什么类型的数据,为了解决这种弊端,Python引入了参数注解, 也就是在函数中间使用 ''' '''包裹起来的注释说明
- 使用参数注解既可以避免动态语音的弊端,也可以对函数的参数进行类型注解和对函数的返回值进行类型注解,但要注意参数注解只对函数参数做一个辅助的说明,并不对函数参数进行类型检查
- Functools模块用于高阶函数,作用于或返回其他函数的函数,通常任何可调用对象都可以被视为用于此模块的功能,需要了解更多该模块的知识,可以查看官方文档https://docs.python.org/2/library/functools.html
Day23:文件操作
python中文件操作的一般分为三个步骤:打开文件,读取文件/写入文件,关闭文件
打开文件会用到open()函数,它的语法为:
open(name[,mode[,buffering]])
,其中文件名是必须的,而模式和缓冲参数都是可选的'r':只读模式(文件的指针将会放在文件的开头)
'w':只写模式(每次都是从开头开始写,所以会覆盖文件已用的内容)
'a':追加模式,如果不想覆盖文件内容可以选择这种模式
'b':二进制模式
'+':读写,给只读赋予写的能力,给只写赋予只读的能力
读取文件会用到read()方法,用于从文件中读取指定的字符数,如果未给定字符数或为负值则表示读取所有文件中字符(如果文件非常大,尤其是大于内存时,无法使用read()方法),在调用open()函数打开文件时,传入标识符'r'或者'rb'表示读取文本文件或读取二进制文件
文件写入会用到write()方法,用于写入指定内容到文件中,在调用open()函数打开文件时,传入标识符'w'或者'wb'表示写文本文件或写二进制文件
在文件读取过程中使用了文件指针这个概念,在一开始文件指针是指向文件内容的开端的,然后随着读写的指针一步一步往后挪
当mode模式为'a'追加时,文件指针指向文件末尾,这是我们可以通过f.seek(0)把指针移回来,seek(****offset****)方法的参数指的是指针偏移的字节
我们还可以通过tell()方法显示指针的当前位置
flush()方法是原来刷新缓冲区的,一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法
在读写完文件之后我们需要关闭文件,close() 方法用于关闭一个已打开的文件,关闭后的文件不能再进行读写操作, 否则会触发 ValueError 错误,使用 close() 方法关闭文件是一个好的习惯
文件操作中使用上下文管理器的好处在于保证文件被关闭, 打开文件操作的时候,抛异常也会关闭,不需要写f.close()来关闭文件了
Day24:IO模块的使用
StringIO经常被用来作字符串的缓存,因为StringIO的一些接口和文件操作是一致的,也就是说同样的代码,可以同时当成文件操作或者StringIO操作
要读取StringIO,可以用一个str初始化StringIO,然后像读文件一样读取
当使用read()方法读取写入的内容时,则需要先用seek()方法让指针移动到最开始的位置,否则读取不到内容
我们可以使用getvalue()方法写入后的字符串
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO
BytesIO实现了在内存中读写bytes,写入的不是str,而是经过UTF-8编码的bytes
要读取BytesIO,可以用一个bytes初始化BytesIO,然后像读文件一样读取
Day25:文件操作修改模块
os**** 模块提供了非常丰富的方法用来处理文件和目录,最为常用的就是path路径操作,操作的语法为os.path.方法名()
使用os.path.abspath(path)****方法获取当前文件的全路径
使用os.path.****dirname(****path****)方法获取当前文件的目录全路径,所带参数为文件全路径
使用os.path.****join(****path1[, path2[, ...]]****)方法拼接路径
使用os.path.****basename(****path****)方法获取文件名
使用os.path.****split(****path****)方法获取目录和文件名,所得结果为一个元组
pathlib 模块提供了一组面向对象的类,这些类可代表各种操作系统上的路径,程序可通过这些类操作路径;使用pathlib模块需要导入Path类,将Path类实例化为一个path对象,或者直接使用Path类初始化新的路径,更多关于pathlib 模块的方法可以查看官方文档:https://docs.python.org/3/library/pathlib.html
sys模块提供对解释器使用或维护的一些变量的访问,以及与解释器强烈交互的函数,更多关于sys模块的介绍可以查看官方文档:https://docs.python.org/3/library/sys.html
shutil模块对文件和文件集合提供了许多高级操作,特别是提供了支持文件复制和删除的功能
模块中的
shutil.copy(src,dst )
方法可以将文件src复制到文件或目录dst中,如果dst是目录, 则在指定的目录中创建(或覆盖)与src具有相同基本名称的文件,权限位被复制, src和dst是以字符串形式给出的路径名模块中的
shutil.move(src,dst )
方法可以递归地将文件或目录(src)移动到另一个位置(dst),如果目标是现有目录,则src将在该目录中移动。如果目标已存在但不是目录,则可能会根据os.rename()语义覆盖目标更多关于shutil模块可以查看官方文档:https://docs.python.org/2/library/shutil.html
Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定,对于可变或包含可变项的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本,copy模块提供了通用的浅层和深层复制操作
copy.copy(x)
返回x的浅表副本,也就是浅拷贝,copy.deepcopy(x[,备忘录])
返回x的深层副本,也就是深拷贝,更多关于copy模块的内容可以查看官方文档:https://docs.python.org/3/library/copy.html
Day26:序列化与反序列化
pickle模块实现了用于序列化和反序列化Python对象结构的二进制协议,'Pickling'是将Python对象层次结构转换为字节流的过程, 'unpickling'是反向操作,从而将字节流(来自二进制文件或类似字节的对象)转换回对象层次结构
序列化是将内存中的数据转换为字节序列保存到文件,而反序列化是将字节序列的文件中的内容恢复到内存中
要序列化对象层次结构,只需调用该dumps()函数,而如果要对数据流进行反序列化,可以调用loads()函数,但是如果要对序列化和反序列化进行更多控制,可以分别创建一个Pickler或一个Unpickler对象
JSON是一种轻量级的数据交换格式,易于人阅读和编写,通过Python的json模块,可以将字符串形式的json数据转化为字典,也可以将Python中的字典数据转化为字符串形式的json数据
json字符串转为字典可以使用json.load()方法或者json.loads()方法,两个方法区别在于,json.load()用于从json文件中读取数据,json.loads()用于将序列化的字符串转化为字典类型
字典转换为json字符串可以使用json.dump()方法或者** json.dumps()**方法,两个方法的区别为json.dump()将数据类型转换成json字符串并存储在文件中, json.dumps()仅能把数据类型转换成字符串但不能保存到文件
msgpack模块是一个基于二进制高效的对象化序列类库,可用于跨语言通信
使用msgpack模块需要先在项目中安装msgpack模块:
Pip install msgpack-python
,然后再导入使用packb()方法
可以将对象序列化成一个二进制对象,unpackb()方法
可以将对象还原
Day27:命令行参数解析
argparse模块是python标准库里面用来处理命令行参数的库,大多数情况下,脚本很可能需要多个参数,而且每次参数的类型用处各不相同,那么这个时候在参数前添加标签表明参数的类型和用途便十分有用,而利用argparse模块可以很方便得实现这一目的
**argparse模块的使用步骤 **
import argparse
:首先导入该模块parser = argparse.ArgumentParser()
:然后创建一个解析对象parser.add_argument()
:然后向该对象中添加你要关注的命令行参数和选项,每一个add_argument方法对应一个你要关注的参数或选项parser.parse_args()
:最后调用parse_args()方法进行解析创建解析器对象ArgumentParser
ArgumentParser(prog=None, usage=None,description=None, epilog=None, parents=[],formatter_class=argparse.HelpFormatter, prefix_chars='-',fromfile_prefix_chars=None, argument_default=None,conflict_handler='error', add_help=True)
prog:程序的名字,默认为sys.argv[0],用来在help信息中描述程序的名称
usage:描述程序用途的字符串
description:参数帮助信息help之前的文本
epilog:参数帮助信息help之后的文本
add_argument()方法,用来指定程序需要接受的命令参数
add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
name or flags:参数有两种,可选参数和位置参数
action:参数动作
nargs :指定这个参数后面的value有多少个
const : action 和 nargs 所需要的常量值
default :不指定参数时的默认值
type :命令行参数应该被转换成的类型