day19 装饰器
Python之路,Day7 = Python基础7
random
wrapper 包装材料;包装纸;书皮
global a 全局的(也就是,函数最外面的那个)
nonlocal a 局部的,上层的函数的变量,如果函数中没有,不会去全局变量中找,直接报错
# 闭包函数: 1.内部函数 2.对外部作用域的引用(全局变量除外)
# 闭包函数的特点:
自带作用域
延迟计算或惰性计算
f.__closure__ 所有的闭包函数都有这个方法,也就是说,如果有这个方法,就证明它是闭包函数
f.__closure__[0].cell_contents 查看闭包函数里面的外部包含的变量(只包含自己调用的那个变量)
装饰器
定义:装饰器本质为任意可调用的对象,被装饰的对象也可以为任意可调用的对象。。。
功能:在不修改被装饰对象的源代码及调用方式的前提下,为其添加新功能
原则:
1.不修改源代码
2.不修改调用方法
语法:
在被装饰的函数上方的一行协商 @装饰器的名字
def outer(func):
def inner(*args, **kwargs):
print("111")
res = func(*args, **kwargs)
print('222')
return res
return inner
======================homework=============
一:编写函数,(函数执行的时间是随机的)
二:编写装饰器,为函数加上统计时间的功能
三:编写装饰器,为函数加上认证的功能
四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "Always"
# Date: 2017/6/14 import time, random auth = {'login':False} def aut():
"""
从文件读取用户名和密码,从而验证是否登录成功
登陆成功后,修改登陆状态
"""
while True:
username = input('username:').strip()
password = input('password:').strip()
if not username or not password:continue with open('username', 'r', encoding='utf-8') as f:
for i in f:
userinfo = eval(i.strip())
if username == userinfo['name'] and password == userinfo['password']:
auth['login'] = True
return 1
else:
print('Inout Error...') def check(func):
"""
检查 auth 的登陆状态,如果为 False, 需要验证,否则,不需要验证
:return:
"""
def wrapper(*args, **kwargs):
if auth['login'] == False:
aut()
func()
return wrapper def timmer(func):
"""
这个是装饰器
为函数添加一个新功能:打印运行程序时使用花费的时间
:return:
"""
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
stop_time = time.time()
print('All cost %s.'%(stop_time - start_time))
return res return wrapper
@check
@timmer
def say_hello():
"""
打印一个 hello。。。 ,每个字母间隔随机秒
:return:
"""
for i in 'Hello。。。':
print(i)
time.sleep(random.randrange(1,2)) @check
@timmer
def say_goodbye():
for i in 'goodbye。。。':
print(i)
time.sleep(random.randrange(1, 2)) # say_hello() say_hello()
say_goodbye()
五:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
六:为题目五编写装饰器,实现缓存网页内容的功能:
具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
七:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "Always"
# Date: 2017/6/14 import os, sys, time
if not os.path.exists(r'缓存'):
os.mkdir(r'缓存') 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): file_name = args[0].split('.')[1]
if os.path.exists(r'缓存/%s'%file_name) and os.path.getsize(r'缓存/%s'%file_name) > 0:
with open(r'缓存/%s'%file_name, 'rb') as f:
print('缓存已经存在,正在读取。。。')
time.sleep(2)
return f.read() # 将新网址加入字典中
url_dict[file_name] = args[0] print('正在从网上下载。。。')
time.sleep(2)
res = func(*args, **kwargs)
# print(res)
# print(type(res)) # print(res)
# input()
with open(r'缓存/%s' % 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 = []
for c, i in enumerate(url_dict):
choose_list.append(i)
print(' %s %s\t\t%s'%(c+1, i, url_dict[i]))
choose = input('\n请输入序号或直接输入网址:http://www.baidu.com\n>>>').strip()
if choose.upper() == "Q":
break
elif choose.isdigit() and 0 < int(choose) <= len(choose_list): res = get(url_dict[choose_list[int(choose) - 1]])
print(res)
elif 'http://' in choose:
res = get(choose)
print(res)
else:
print('输入错误')
time.sleep(2)
初写代码,BUG,不足之处自然很多,如有问题,欢迎指出。
谢谢!!!
day19 装饰器的更多相关文章
- Python高手之路【四】python函数装饰器
def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...
- python装饰器
今天看了装饰器的一些内容,感觉@修饰符还是挺抽象的. 装饰器就是在不用改变函数实现的情况下,附加的实现一些功能,比如打印日志信息等.需要主意的是装饰器本质是一个高阶函数,她可以返回一个函数. 装饰器需 ...
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- [原创]django+ldap实现单点登录(装饰器和缓存)
前言 参考本系列之前的文章,我们已经搭建了ldap并且可以通过django来操作ldap了,剩下的就是下游系统的接入了,现在的应用场景,我是分了2个层次,第一层次是统一认证,保证各个系统通过ldap来 ...
- PHP 装饰器模式
装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...
- python cookbook 学习系列(一) python中的装饰器
简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...
- python基础补漏-05-生成器和装饰器
[1]生成器 很难用简单的语言描述生成器. 生成器:从字面上来理解,就是以某种规则为基础,不断的生成数据的工具 生成器函数: 在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器 ...
- python --> 递归 以及装饰器
一.递归知识 函数迭套执行,逐层执行之后,满足某个条件之后就会停止执行,将return值返回上层的函数,上层函数再逐层返回,最终返回给最初始函数. 递归在斐波那契数列的应用[斐波那契数列特点:前两个数 ...
- python 装饰器的理解
一. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷 ...
随机推荐
- Django学习铺垫
Web框架本质 所有的web服务本质都是一个socket服务端,用户浏览器就是一个socket客户端,这样就实现了自己的web框架 ,但是自己的写的框架肯定很low,各种工能崩溃,所以我们就要学习py ...
- 前端自动化构建工具——gulp环境搭建教程
gulp是前端工程化的工具,它可以对html,css,js等代码和图片进行压缩,也可以对sass和less等预处理语言进行编译,代码部署.gulp学起来简单,用起来方便,大大提高我们工作效率. 这里可 ...
- 文件上传到ftp服务工具类
直接引用此java工具类就好 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcep ...
- 百度网盘Mac版如何分享链接?创建百度网盘 for Mac分享链接的方法
想把自己百度网盘里的数据分享给朋友,该怎么操作呢?有很多朋友使用百度网盘,可以很轻松的自己的文件上传到网盘上,并可跨终端随时随地查看和分享.下面Mac down小编就给大家介绍一下创建百度网盘 for ...
- Servlet - Tomcat服务器相关
1. 服务器 : 服务器其实就是代码编写的一个程序, 可以根据用户发送的请求, 调用执行对应的逻辑代码 2. Tomcat目录结构说明 : \bin : 存放启动和关闭Tomcat的可执行文件 \co ...
- R语言 数据类型
R语言数据类型 通常,在使用任何编程语言进行编程时,您需要使用各种变量来存储各种信息. 变量只是保留值的存储位置. 这意味着,当你创建一个变量,你必须在内存中保留一些空间来存储它们. 您可能想存储各种 ...
- 揭秘!2周实现上云上市,阿里云SaaS上云工具包如何打造新云梯?
提到“上云”,很多人会理解成上IaaS,比如买一些计算.存储和网络云产品,把自己的应用系统部署上去.这的确是通常意义的上云.但对SaaS而言,需要从产品.商业.服务,三个维度考虑SaaS伙伴和客户的痛 ...
- QueryList 内容过滤
<?php require 'vendor/autoload.php'; use QL\QueryList; $html =<<<STR <div id="de ...
- CF696B Puzzles(期望dp)
传送门 解题思路 比较有意思的一道题.首先假如这个点\(x\)只有\(1\)个儿子\(u\),那么显然可得\(dp[u]=dp[x]+1\).继续如果多加一个儿子\(p\),那么\(p\)在\(u\) ...
- Wannafly挑战赛21-A-灯塔-内含正确的凸包模版
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 目录 目录 题意:传送门 思路: AC代码: 题意:传送门 题目描述 Z市是一座港口城市,来来往往的船只依靠灯塔指引方向. 在海平面上 ...