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 可以当作参数传递 ...
随机推荐
- Use on Git
Preface The document is about to introduce some specialties on PLM development and mainte ...
- C#操作Word的+ CKEditor 輸出成Word文件(包含圖案上傳)
C#操作Word 参考博文: C#操作word类文件 https://www.cnblogs.com/walking/p/3571068.html C#中的Office操作专栏(21) http:// ...
- 解决MSF更新证书错误
如下图所示提示签名无效下载失败,导致更新不了msf 解决办法如下: echo 'deb http://apt.metasploit.com/ lucid main' > /etc/apt/sou ...
- session复制
环境描述:(三台服务器 系统:7.6)192.168.200.111 nginx192.168.200.112 tomcat192.168.200.113 tomcat环境配置:192.168.200 ...
- BCZM : 2.1
1.问题描述 实现一个函数,输入一个无符号整数,输出该数二进制中的1的个数.例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2 2.分析与解法 解法1:利用十进制和二进制相互转化 ...
- git删除远程服务的文件夹
首先查看当前分支:git branch -a 删除缓存的idea:git rm --cached -r .idea 提交gitiginore文件,将.idea从源代码仓库中删除(-m 表示注解): ...
- linux秘钥登录
秘钥登录首先要了解四个文件: 公钥文件,私钥文件, authorized_keys, 还有/etc/ssh/sshd_config配置文件. 公钥文件存放在被登陆的机器上, 要将公钥添加进author ...
- php fopen用法以及解释
$log = fopen('./log.txt','a');//生成一个log.txt文件,a相当于文件的权限 fwrite($log,'成功'."\r\n");//写入文件 mo ...
- 线程池 一 ThreadPoolExecutor
java.util.concurrent public class ThreadPoolExecutor extends AbstractExecutorService ThreadPoolExecu ...
- vue wabpack 切换开发环境 和生成环境 的接口地址
/config/dev.env.js 新增一行 var merge = require('webpack-merge') var prodEnv = require('./prod.env') mod ...