day20 装饰器补充
Python之路,Day8 = Python基础8
装饰器
from functools imoort wraps # 保留原函数所有信息,比如:用__doc__查看注释的时候,显示原来的注释
def func01(func):
@wraps(func) # 用__doc__查看注释的时候,显示原来的注释
def wrapper(*args, **kwargs):
print('func01---------------------01')
res = func(*args, **kwargs)
print('func01---------------------02')
return res
# 上面的效果就相当于在这里加了一句 wrapper.__doc__ = func.__doc__
return wrapper
装饰器的参数:
再包一层
def doco(file_type = 'file'):
def outer(func):
def wrapper(*args, **kwargs):
if file_type == 'file':
print('with open file')
elif file_type == 'mysql':
print('deal with mysql')
else:
print('i do not konw how to deal')
res = func(*args, **kwargs)
return res
return wrapper
return outer @doco('file')
def func1():
print('fucn1') @doco('mysql')
def func2():
print('fucn2') @doco('abc')
def func3():
print('fucn3') func1()
func2()
func3()
迭代器
1.重复
2.基于上一次的结果
可迭代对象:
python为了提供一种不依赖于索引的迭代方式,
会为一些对象内置 __iter__ 方法,
obj.__iter__称为可迭代的对象
obj.__iter__() 得到的结果就是迭代器
得到的迭代器,既有__iter__又有__next__方法
__iter__:
__next__: 返回下一个值
好处:
1.可以不依赖索引
2.惰性计算,节省内存
缺点:
1.取值麻烦,需要一个一个取值
2.不能往回取值
3.不能获取迭代器的长度
========================homework================
# 整理今天装饰器代码(每人手写一份,注意,是手写,交到小组长手里,明天我检查),准备明天默写
def demeo(file_type = 'file'):
def outer(func):
def inner(*args, **kwargs):
if file_type == 'file':
print('deal with \033[35;0mfile\033[0m...')
elif file_type == 'mysql':
print('deal with \033[35;0mmysql\033[0m...')
else:
print("deal with \033[35;0mothers\033[0m...")
res = func(*args, **kwargs)
return res
return inner
return outer @demeo()
def f1():
print("my name is f1...") @demeo('mysql')
def f2():
print('f2 is my name...') @demeo('abc')
def f3():
print('is me, f3...') f1()
f2()
f3()
# 2 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到文件中
# 注意:时间格式的获取
# import time
# time.strftime('%Y-%m-%d %X')
import time log_path = r'C:\Users\Administrator\PycharmProjects\老男孩全栈5期\homework\day08\log\log.log' def outer(func):
def inner(*args, **kwargs):
with open(log_path, 'a', encoding='utf-8') as f:
log_info = time.strftime('%Y-%m-%d %X ') + func.__name__ + ' run\n'
f.write(log_info) res = func() return res
return inner @outer
def f1():
print("This is f1.....") f1()
# 3 判断下列数据类型是可迭代对象or迭代器
#
# s='hello'
# l=[1,2,3,4]
# t=(1,2,3)
# d={'a':1}
# set={1,2,3}
# f=open('a.txt')
#
# 4 分别用依赖索引和不依赖索引两种方式迭代上述对象
from collections import Iterable s='hello'
l=[1,2,3,4]
t=(1,2,3)
d={'a':1}
set={1,2,3}
f=open('a.txt') def print_while(a):
count = 0
while count < len(a):
print(a[count])
count += 1
def print_for(a):
for i in a:
if isinstance(a, dict):
print(i,a[i])
else:
print(i) print(' s is Iterable: %s'%isinstance(s, Iterable))
print_while(s)
print_for(s) print(' l is Iterable: %s'%isinstance(l, Iterable))
print_while(l)
print_for(l) print(' t is Iterable: %s'%isinstance(t, Iterable))
print_while(t)
print_for(t) print(' d is Iterable: %s'%isinstance(d, Iterable))
# print_while(d)
print_for(d) print('set is Iterable: %s'%isinstance(set, Iterable))
# print_while(set)
print_for(set) print(' f is Iterable: %s'%isinstance(f, Iterable))
# print_while(f)
print_for(f)
# 5 选做题:
# 基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能
# 要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容
import os, time, hashlib #
# print(hash('abcdefg'))
# print(hash('abcdefg')) cach_dir = "C:\\Users\\Administrator\\PycharmProjects\\老男孩全栈5期\\homework\\day08\\cach\\" # 设置一个缓存的目录
print(cach_dir) if not os.path.exists(cach_dir): # 查看缓存目录是否存在,如果不存在,创建
os.mkdir(cach_dir) url_dict = {'baidu':'http://www.baidu.com',
'52pojie':'http://www.52pojie.cn',
} # 创建一个字典,将已经知道的网址放入里面,下次可以继续使用 from urllib.request import urlopen # 导入一个可以下载网页的模块 def wrapper(func):
"""
这是个装饰器,主要的作用是接收一个url的路径,然后返回这个网页的代码
:param func:
:return:
"""
def inner(*args, **kwargs): url_name = args[0] # url_name,就是想要下载的网页的名字
sha1 = hashlib.sha1() # 调用加密算法 sha1
sha1.update(url_name.encode()) # 将url 进行加密,得到结果,后期用来查看缓存是否存在
sha1_name = sha1.hexdigest() # 将加密后的 url(字符串) ,赋值给 sha1_name
file_name = cach_dir + sha1_name # 确定文件路径 url_dict[args[0].split('.')[1]] = args[0] # 将网页信息写入字典中,如果存在,则更新 if os.path.exists(file_name) and os.path.getsize(file_name) > 0: # 判断缓存文件是否存在,大小是否大于 0
with open(file_name, 'rb') as f: # 打开文件,并且用 rb 二进制的方式打开
print('缓存已经存在,正在读取。。。')
time.sleep(2)
return f.read() # 将新网址加入字典中 # url_dict[args[0].split('.')[1]] = args[0] # 将网页信息写入字典中,如果存在,则更新 print('正在从网上下载。。。')
time.sleep(2)
res = func(*args, **kwargs) with open(file_name, 'wb') as f:
f.write(res)
# input('回车键结束。。。。')
return res
return inner @wrapper
def get(url):
return urlopen(url).read() # res = get('http://www.baidu.com')
# print(res.decode()) # print(get('http://www.baidu.com').decode()) while True:
choose_list = [] # 这里我定义了一个列表,主要是把存放地址的字典的 key 放进去,因为字典是无须的,我想实现输入序号(下表)的方式选择地址,用列表的话,可以实现数字(下标)对应列表元素(字典的keys)
for c, i in enumerate(url_dict): # 打印序号,并循环打印字典的keys
choose_list.append(i) # 分别将 每个 key 放入到列表中,这样的话,下面打印选项的时候,我就可以通过对应关系找到 用户所选择的网址是哪一个
print(' %s %s\t\t%s'%(c+1, i, url_dict[i])) # 将字典中的内容打出来,例如: 1 baidu www.baidu.com
choose = input('\n请输入序号或直接输入网址:http://www.baidu.com\n>>>').strip() # 这里获取一个用户的选择
if choose.upper() == "Q": # 如果选择是 'q' 或者 'Q', 那么退出
break
elif choose.isdigit() and 0 < int(choose) <= len(choose_list): # 如果 choose 是数字,而且,数字的大小等于列表的长度(也就是说选择范围为打印菜单的序号) res = get(url_dict[choose_list[int(choose) - 1]]) # 那么,就把这个选择对应的网址传给函数 get(), 得到的返回值给 res
print(res)
elif 'http://' in choose: # 如果, choose 中包含 'http://' 这几个字符的话,我就认为,你输入了一个完整的网址
res = get(choose) # 这个时候,我就将这个完整的网址传个 get() 函数,将返回值给 res
print(res)
else: # 如果都不满足,提示输入错误
print('输入错误')
time.sleep(2)
day20 装饰器补充的更多相关文章
- Python札记 -- 装饰器补充
本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...
- python day6 装饰器补充,正则表达式
目录 python day 6 1. 装饰器decorator 2. 正则表达式re 2.1 正则表达式概述 2.2 re模块常用方法 python day 6 2019/10/09 学习资料来自老男 ...
- 学到了林海峰,武沛齐讲的Day20 装饰器
import time def timmer(func): #func=test 装饰器架构 def wrapper(): start_time=time.time() func() #就是在运行te ...
- python基础语法_9-1闭包 装饰器补充
1.闭包的概念 closure:内部函数中对enclosing作用域的变量进行引用,外部函数返回内部函数名 2.函数实质与属性 函数是一个对象:在内存中有一个存储空间 函数执行完成后内部变量回收: ...
- python之装饰器补充与递归函数与二分查找
目录 多层装饰器 有参装饰器 递归函数 基本演示 斐波那契数列 总结 小拓展 算法之二分法 简介 举例 总结 多层装饰器 我们已经知道了语法糖的作用是将装饰对象自动装饰到装饰器中,一个语法糖的应用我们 ...
- Day4 装饰器——迭代器——生成器
一 装饰器 1.1 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多 ...
- python之函数对象、函数嵌套、名称空间与作用域、装饰器
一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if de ...
- python学习day14 装饰器(二)&模块
装饰器(二)&模块 #普通装饰器基本格式 def wrapper(func): def inner(): pass return func() return inner def func(): ...
- python基础知识13---函数对象、函数嵌套、名称空间与作用域、装饰器
阅读目录 一 函数对象 二 函数嵌套 三 名称空间与作用域 四 闭包函数 五 装饰器 六 练习题 一 函数对象 1 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 ...
随机推荐
- sanic中间件和监听器
一:中间件 中间件是服务器在请求之前或之后执行的功能,他们可以用来修改修改用户定义处理函数的请求或相应. Sanic提供两种类型的中间件:请求和响应. 两者都是使用@app.middleware装饰器 ...
- Java 四种内部类
静态内部类:类中静态类 成员内部类:类中非静态类 局部内部类:类中方法中有名字的类 匿名内部类:类中方法中无名的类 引言:在Java中通常情况下,一个类中会有属性和方法,但还可以包含内部类,内部类可以 ...
- Linux 中 sqlite3 基本操作
https://www.runoob.com/sqlite/sqlite-commands.html 一 .linux 下安装数据库和创建一个数据库 1. Linux 下安装sqlite3 需要两个命 ...
- layerui ios不适应问题
.admin-main {-webkit-overflow-scrolling: touch; overflow: scroll; position: absolute; left: 0; top: ...
- 用python输出1-100之间所有的质数
# 1-100之间的质数 i = 2 while i <= 100: j = 2 flag = True while j < i: if i % j == 0: flag = False ...
- HashMap是不是有序的?
不是有序的. 有没有有顺序的Map实现类? 有TreeMap和LinkedHashMap. TreeMap和LinkedHashMap是如何保证它的顺序的? LinkedHashMap 是根据元素增加 ...
- Java位运算总结
关于位运算,以前也见过,搜过,当时会用了,过后就忘了,今天好好学习一遍,然后整理一下. Java中的位运算,涉及到计算机的二进制,位用bit表示,1Byte=8bit,根据各种基本数据类型占用的字节空 ...
- DIV内容超出固定宽度部分用省略号代替
方法一:CSS控制溢出文本 只针对DIV单行数据展示 /** DIV文本超出宽度部分用...替换,鼠标移上显示全部 **/ .textAuto{overflow:hidden;text-overfl ...
- Android 配置正式签名和debug签名
为了测试微信分享,微信分享必须有签名信息才能成功调用微信,所以需要debug 下设置签名,方便调试build.gradle里,配置2个签名: signingConfigs { release { ke ...
- 2018-2019-2-20175323 java实验三敏捷开发与XP实践
代码规范 安装alibaba插件 首先使用code栏里面的reformat code使代码的格式更加规范 再用编码规约扫描,alibaba把问题分为block/critical/major三个等级,出 ...