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 装饰器的更多相关文章

  1. Python高手之路【四】python函数装饰器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

  2. python装饰器

    今天看了装饰器的一些内容,感觉@修饰符还是挺抽象的. 装饰器就是在不用改变函数实现的情况下,附加的实现一些功能,比如打印日志信息等.需要主意的是装饰器本质是一个高阶函数,她可以返回一个函数. 装饰器需 ...

  3. Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

    本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...

  4. [原创]django+ldap实现单点登录(装饰器和缓存)

    前言 参考本系列之前的文章,我们已经搭建了ldap并且可以通过django来操作ldap了,剩下的就是下游系统的接入了,现在的应用场景,我是分了2个层次,第一层次是统一认证,保证各个系统通过ldap来 ...

  5. PHP 装饰器模式

    装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...

  6. python cookbook 学习系列(一) python中的装饰器

    简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...

  7. python基础补漏-05-生成器和装饰器

    [1]生成器 很难用简单的语言描述生成器. 生成器:从字面上来理解,就是以某种规则为基础,不断的生成数据的工具 生成器函数: 在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器 ...

  8. python --> 递归 以及装饰器

    一.递归知识 函数迭套执行,逐层执行之后,满足某个条件之后就会停止执行,将return值返回上层的函数,上层函数再逐层返回,最终返回给最初始函数. 递归在斐波那契数列的应用[斐波那契数列特点:前两个数 ...

  9. python 装饰器的理解

    一. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷 ...

随机推荐

  1. 微信小程序之评分页面

    首先给大家看看做好的效果图: 一.接下来我们说一下评分这个功能: 实际上就是一个简单的js,首先我们遍历出小星星,此时默认给的五星好评,在给他们一个点击事件,当点击时,我们获取到当前点击的是第几颗:代 ...

  2. $router和$route的区别,路由跳转方式name 、 path 和传参方式params 、query的区别

    一.$router和$route的区别 $router : 是路由操作对象,只写对象$route : 路由信息对象,只读对象 例子://$router操作 路由跳转 this.$router.push ...

  3. 错误 175: 具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序未在计算

    问题描述:错误 175: 具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序未在计算 原因描述:一.首先我的系统是因为是win10 的有问题,重新装了系统. 二. ...

  4. Visio2016专业版永久激活码

    Visio2016专业版永久激活码: [Key]:NKVJM-8MTT4-8YDFR-6738M-DPFJH [Key]:W9WC2-JN9W2-H4CBV-24QR7-M4HB8 [Key]:7K8 ...

  5. 干货满满!解密阿里云RPA (机器人流程自动化)的产品架构和商业化发展

    阿里云RPA,作为阿里云自研8年的技术,在资本的热捧下,逐渐从幕后来到台前,成为企业服务市场的黑马.本文将从产品上全面剖析,阿里云RPA这款产品的现阶段情况,同时简单谈谈阿里云RPA的商业化进展. 阿 ...

  6. GDI+图像与GDI位图的相互转换

    Delphi的TBitmap封装了Windows的GDI位图,因此,TBitmap只支持bmp格式的图像,但是在Delphi应用程序中,常常会遇到图形格式的转换,如将Delphi位图TBitmap的图 ...

  7. ueditor使用心得

    UEditor使用手册 配置jdk 1.6+ Apache Tomcat6.0+ Ueditor官网下载 部署 安装好jdk和apache后,我们开始部署代码 我们在apache的安装目录下,找到we ...

  8. 高效率使用google,国外搜索引擎,国内顺利使用Google的另类技巧,可用谷歌镜像, 可用google学术, 如何使用robots不让百度和google收录

    Google良好的搜索和易用性已经得到了广大网友的欢迎,但是除了我们经常使用的Google网站.图像和新闻搜索之外,它还有很多其他搜索功能和搜索技巧.如果我们也能充分利用,必将带来更大的便利.这里我介 ...

  9. Java 并发总结(三)

    锁优化及注意事项 有助于提高锁的性能 减小所持有时间:例如不要对方法直接加锁,而是在方法中对具体访问临界资源的代码加锁 减小锁粒度:如ConcurrentHashMap 用读写锁代替独占锁 锁分离:如 ...

  10. IP总结

    网络层向上只提供无连接的.尽最大努力支付的数据报服务 IP地址,32位,分为两部分,网络和主机标示 IP地址分类: A类:0开头,1-8位为网络标示 B类:10开头,1-16位为网络标示 C类:110 ...