python笔记(13)--带参数装饰器和常用模块(os/sys/time/datetime)
内容目录
- 带参数的装饰器:flask框架 + dijango缓存 + 写装饰器实现被装饰的函数要执行N次
- 模块
- os
- sys
- time(三种类型)
- datetime 和 timezone【了解】
内容回顾&补充
1.函数
写代码的方式:面向过程 ---》函数式编程 ---》面向对象编程
1.1函数基础
def func(a1,a2):
pass
result = func(1,2)
1.2参数
补充:对于函数的默认值慎用可变类型
# 如果要想给value设置默认是空列表
#不推荐(坑)
def func(data,value=[]):
pass
#推荐
def func(data,value=None):
if not value:
value = []
面试题:
- def func(a,b = [ ])有什么陷阱
- 看代码写结果
def func(a,b=[]):
b.append(a)
return b
list1 = func(1)
list2 = func(2,[11,22,33])
list3 = func(3)
print(list1,list2,list3)
#l1 = [1,3]
#l2 = [11,22,33,2]
#l3 = [1,3]
#解析:因为传参的时候,函数内使用的是自己的列表,l1结果运行后函数内有列表[1],l3运行则在函数内的列表中增加了参数值。但是l2使用的是传参进去的列表,所以不受影响
1.3返回值
闭包:
# 不是闭包
def func1(name):
def inner():
return 123
return inner
# 是闭包:封装值 + 内层函数需要使用。
def func2(name):
def inner():
print(name)
return 123
return inner
1.4作用域
1.5递归
-
函数自己调用自己。(效率低,容易爆栈)
-
递归默认最大次数为1000。
def func(): print(1) func() func()
def func(i): print(i) func(i+1) func(1)
#用函数可以实现斐波那契数列 def func(a,b): print(b) func(b,a+b) func(0,1)
2.模块
- hashlib
- random
- getpass
- time
内容详细
1.装饰器
1.1基本格式
1.2关于参数
#标准格式,必须加万能参数,好处是其他函数使用该装饰器时无需关注原函数的参数
def x1(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@x1
def f1():
pass
@x1
def f2(a1):
pass
@x1
def f3(a1,a2):
pass
1.3关于返回值
def x1(func):
def inner(*args,**kwargs):
data = func(*args,**kwargs)
return data
return inner
@x1
def f1():
print(123)
v1 = f1() #v1 = None
1.4关于前后
def x1(func):
def inner(*args,**kwargs):
print('调用原函数之前')
data = func(*args,**kwargs)#执行原函数并获取返回值
print('调用原函数之后')
return data
return inner
@x1
def index():
print(123)
index()
重点作业详解
1.请为以下函数编写一个装饰器,添加上装饰器后可以实现:执行 read_userinfo 函时,先检查文件路径是否存在,如果存在则执行后,如果不存在则 输入文件路径不存在,并且不再执行read_userinfo函数体中的内容,再讲 content 变量赋值给None。
def read_userinfo(path):
file_obj = open(path,mode='r',encoding='utf-8')
data = file_obj.read()
file_obj.close()
return data
content = read_userinfo('/usr/bin/xxx/xxx')
"""
温馨提示:如何查看一个路径是否存在?
import os
result = os.path.exists('路径地址')
# result为True,则表示路径存在。
# result为False,则表示路径不存在。
"""
############解 答#############
import os
def index(arg):
def inner(*args,**kwargs):
#检查路径是否存在
path = args[0] #*args传参进来为一个元组,如要拿哪个元素,可以使用元组下标表示
if not os.path.exists(path):
print('路径不存在')
return
data = arg(*args, **kwargs)
return data
return inner
@index
def read_userinfo(path):
file_obj = open(path,mode='r',encoding='utf-8')
data = file_obj.read()
file_obj.close()
return data
content = read_userinfo('D:\pycharm_project\python36\log.txt')
print(content)
1.5带参数的装饰器
#第一步:执行 ret = xxx(index)
#第二步:将返回值赋值给 index = ret
@xxx
def index():
pass
#第一步:执行 v1 = uuu(9)
#第二步:ret = v1(index)
#第三步:index = ret
@uuu(9)
def index():
pass
# ###############普通装饰器################
def wrapper(func):
def inner(*args,**kwargs):
print('执行之前')
data = func(*args,**kwargs)
print('执行之后')
return data
return inner
@wrapper
def index():
pass
# ###############带参数装饰器################
#相当于可以带参数的装饰器,函数中没有就往父级函数中找参数
def x(counter):
def wrapper(func):
def inner(*args,**kwargs):
print('执行之前')
data = func(*args,**kwargs)
print('执行之后')
return data
return inner
return wrapper
@x(9) # index = 先执行x(9)函数,拿到返回值(内层函数wrapper),再执行wrapper(index)
def index():
pass
练习题:
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,每次结果添加到列表中,最终返回列表
import random
def xxx(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
v = [func(*args,**kwargs) for i in range(counter)]
return v
return inner
return wrapper
@xxx(6)
def index():
return random.randint(1,6)
v = index()
print(v)
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,每次结果添加到列表中,返回最后一次执行的结果【面试题】
import random
def xxx(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
v = [func(*args,**kwargs)]
return v
return inner
return wrapper
@xxx(6)
def index():
return random.randint(1,6)
v = index()
print(v)
1.6 自学补充
-
元数据:flask框架
-
多个装饰器:flask框架
@x1 @x2 def func(): pass
总结:
基本装饰器(更重要)
def x1(func):
def inner(*args,**kwargs):
print('调用原函数之前')
data = func(*args,**kwargs)#执行原函数并获取返回值
print('调用原函数之后')
return data
return inner
@x1
def index():
print(123)
index()
带参数的装饰器:
#相当于可以带参数的装饰器,函数中没有就往父级函数中找参数
def x(counter):
def wrapper(func):
def inner(*args,**kwargs):
print('执行之前')
data = func(*args,**kwargs)
print('执行之后')
return data
return inner
return wrapper
@x(9) # index = 先执行x(9)函数,拿到返回值(内层函数wrapper),再执行wrapper(index)
def index():
pass
2.模块
2.1 sys模块
-
sys.getrefcount:获取一个值的应用计数
import sys #获取一个值的应用计数 a = [11,22,33] b = a print(sys.getrefcount(a)) #输出为3
-
sys.getrecursionlimit:查询python默认支持的递归最大值
import sys #python默认支持的递归最大值 v1 = sys.getrecursionlimit() print(v1) #结果为1000
-
sys.stdout.write --> 相当于print()
- 示例:进度条
- \r 为覆盖原值,取最后一值
#进度条示例: import sys import time for i in range(1,101): msg = "%s%%\r" %i print(msg,end = '') time.sleep(0.05)
- 示例:进度条
-
进度条示例:文件复制并取读取文件的进度条
#读取文件并写入进度条,将文件复制到另一个文件中。 import os #1.获取文件的大小 file_size = os.stat('20190904.mp4').st_size #os模块中st_size为获取文件大小(字节) #一点一点的读取文件,并写入a.mp4文件中 read_size = 0 with open('20190904.mp4',mode="rb") as f1,open('a.mp4',mode='wb')as f2: while read_size < file_size: chunk = f1.read(1024) #每次最多读取1024字节 f2.write(chunk) read_size += len(chunk) val = int(read_size / file_size * 100) print("%s%%\r"%val,end='')
-
sys.argv:(运维常用(重要))
import sys #获取用户执行脚本时,传入参数 #在CMD中运行该脚本,并传入要删除的文件路径(D:/test) #C:\python36\python36.exe D:/pycharm_project/python36/code01.py D:/test #sys.argv = ['D:/pycharm_project/python36/code01.py','D:/test'] path = sys.argv[1] #此时path = ['D:/test'] print(path) import shutil #使用删除功能的模块 chack = input("是否要删除%s文件,(输入Y确认删除)"%path).strip().upper() if chack == 'Y': shutil.rmtree(path) #删除文件路径的操作 print("删除成功") else: print("已退出当前操作") exit()
#练习题:让用户传参,两个参数,第一个是文件,第二个是内容,把内容追加到文件中去 import sys print(sys.argv) if len(sys.argv) < 3 : print('参数不够,请重新输入') sys.exit(0) else: file_path = sys.argv[1] data_path = sys.argv[2] with open(file=file_path,mode='a',encoding='utf-8') as f: f.write(data_path)
-
sys.exit(0):程序终止,遇到此命令,整个程序终止
import sys def x1(): print(123) def x2(): print(456) x1() sys.exit(0) x2() #只执行x1,不执行x2.
-
sys.path ----后续补充
2.2 os模块
和操作系统相关的数据
-
os.path.exists(path):如果path存在,返回True;如果path不存在,返回False
-
os.stat('20190904.mp4').st_size:获取文件大小
-
os.path.abspath():获取文件的绝对路径
import os path = '20190904.mp4' v1 = os.path.abspath(path) print(v1) #输出为D:\pycharm_project\python36\20190904.mp4,等于path的绝对路径
-
os.path.dirname:获取路径的上级目录
import os path = r'D:\pycharm_project\python36\20190904.mp4' #注意加r,转义符 v1 = os.path.dirname(path) print(v1) #输出为D:\pycharm_project\python36,等于path的上级目录
-
补充(转义)
#字符串前加r等于转义,推荐使用这个 path = r'D:\pycharm_project\python36\20190904.mp4' print(path) #两个反斜杠代表转义 path = 'D:\\pycharm_project\\python36\\n20190904.mp4'
-
-
os.path.join:路径拼接,会根据当前系统进行路径拼接
import os path = r'D:\pycharm_project\python36' v = 'n.txt' result = os.path.join(path,v) print(result) #结果为D:\pycharm_project\python36\n.txt #或者: result1 = os.path.join(path,'n1','n2','n3') print(result) #结果为D:\pycharm_project\python36\n1\n2\n3
-
os.listdir:只列当前目录下所有的文件【第一层】
import os result = os.listdir(r'D:\pycharm_project\python36') for path in result: print(path) #结果为列出了当前目录下所有的文件
-
os.walk:列出该目录下所有的文件,包括文件夹内的路径【所有层】【面试题】
import os result = os.walk(r'D:\pycharm_project\python36') for a,b,c in result: print(a,b,c) #找到路径下所有的文件呢 import os result = os.walk(r'D:\pycharm_project\python36') for a,b,c in result: #a,正在查看的目录 b,此目录下的文件夹 c,此目录下的文件 for item in c: path = os.path.join(a,item) print(path)
-
os.remove(path):删除单个文件
- path是文件的路径,如果这个路径是一个文件夹,则会抛出OSError的错误,这时需用用rmdir()来删除
-
os.rmdir(path):
- path是文件夹路径,注意文件夹需要时空的才能被删除os.unlink('F:\新建文本文档.txt')
-
os.unlink(path):
- 功能和remove一样是删除一个文件,但是删除一个删除一个正在使用的文件会报错。
2.3 shutil删除模块
-
shutil.rmtree():删除树文件,路径下所有的文件全部删除
import shutil shutil.rmtree(path) ###示例### import sys import shutil #使用删除功能的模块 #获取用户执行脚本时,传入参数 #在CMD中运行该脚本,并传入要删除的文件路径(D:/test) #C:\python36\python36.exe D:/pycharm_project/python36/code01.py D:/test #sys.argv = ['D:/pycharm_project/python36/code01.py','D:/test'] path = sys.argv[1] #此时path = ['D:/test'] print(path) chack = input("是否要删除%s文件,(输入Y确认删除)"%path).strip().upper() if chack == 'Y': shutil.rmtree(path) #删除文件路径的操作 print("删除成功") else: print("已退出当前操作") exit()
总体总结:
- 普通装饰器
- 参数
- 返回值
- 前后
- 带参数的装饰器
- 模块
- random
- hashlib
- getpass
- time(重点)
- os(重点)
- sys
- shutil