前言:本节主要学习装饰器

一、装饰器

定义:本质上是个函数,用来装饰其他函数;(就是为其他函数添加附加功能)

原则:1.不能修改被装饰的函数的源代码

   2.不能修改被装饰的函数的调用方式

以上两点可以总结出装饰器对被装饰的函数来说是完全透明的,因为装饰器不能修改原函数的源代码,被装饰的函数还是像往常一样继续运行。

实现装饰器的知识储备:1.函数即‘变量’

           2.高阶函数

           3.嵌套函数

可以理解成:高阶函数 + 嵌套函数 = 装饰器

1.函数即‘变量’

内存回收机制:数据存储在内存中,用变量名来引用;如果把内存比作一栋大厦,数据比作一个房间,变量名相当于门牌号,用门牌号来访问房间;如果删除了变量名,在一段时间内没有引用数据,python的内存回收机制就会回收数据。

函数如同变量:函数和变量一样也有内存回收机制,在定义函数的时候相当于把函数体赋值给了函数名,在内存里面存储着函数体,然后用函数名来引用;匿名函数也是一样,在内存中存储lambda表达式,如果把lambda表达式赋值给一个变量名,就能用变量来引用lambda表达式。

2.高阶函数

满足下面任意一条就可以看做是高阶函数:

a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

b:返回值中包含函数名(不修改函数的调用方式)

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:qinjiaxi
import time def bar():
time.sleep(3)
print('in the test1') def test1(func):
start_time = time.time()
func()
stop_time = time.time()
print("time func run time is %s" % (stop_time-start_time)) test1(bar)

3.嵌套函数

在一个函数体内定义一个函数,而不是在一个函数里面调用函数,这个叫做函数的嵌套。

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:qinjiaxi
x = 2
def grandpa():
x = 1
def father():
x = 2
def son():
x = 3
print(x)
son()
father()
grandpa()

返回值是3

4.装饰器实例

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:qinjiaxi
import time
#timer是装饰器满足嵌套函数(函数里面定义一个函数),满足高阶函数(返回值有函数名)
def timer(func):
def deco(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)#run test1
stop_time = time.time()
print("the func run time is %s" % (stop_time - start_time))
return deco
@timer #test1 = timer(test1)#调用装饰器
def test1():
time.sleep(3)
print("in the test1")
test1()#这个不是上面这个test1函数,其实是运行deco这个内存地址

5.装饰器实例升级版

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:qinjiaxi
import time
user, password = 'qinjiaxi', 'abc123'
def auth(auth_type):
print("auth func", auth_type)
def out_wrapper(func):
def wrapper(*args, **kwargs):
print("wrapper func args", *args, **kwargs)
if auth_type == "local":
username = input("Username:").strip()
passwd = input("Password:").strip()
if user == username and password == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args,**kwargs)#from home
print("-----after authentication-----")
return res
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type == 'ldap':
print("sorry I do not know")
return wrapper
return out_wrapper def index():
print("welcome to index page") @auth(auth_type='local')#home = wrapper /home = out_wrapper(home)
def home():
print("welcome to home page")
return "from home" @auth(auth_type="ldap")#bbs = wrapper
def bbs():
print("welcome to bbs page") index()
print(home())
bbs()

注:装饰器对于初学者来说还是比较难以理解的。实际多debug一下就会理解其中的原理,下面简单的分几个步骤剖析一下(拿上面的升级版实例来说明):

1.当调用装饰器时(实例中的@auth(auth_type = ‘xxxx’))其实程序运行时先找到调用装饰器的位置,从装饰器里面一步一步的return出最里层的函数的内存地址,也就是函数名(实例中的wrapper)

2.返回出最里层函数名后跳到最后面的调用函数部分(实例中最后三行)来调用函数(这个函数其实就是上面最里层的函数)

3.然后执行装饰器最里层的函数,执行到res = func(*args, **kwargs)时候就是调用被装饰的函数

ql的python学习之路-day9的更多相关文章

  1. ql的python学习之路-day15

    前言:本节主要讲解的是文件路径 在实际的软件开发中会设计一个项目的文件目录,按照执行包bin.配置包config.核心包core等来设计,在执行包里面要运行核心包里的主程序mian,由于不在同一级的目 ...

  2. ql的python学习之路-day14

    前言:本节主要学习时间模块time.datetime python中的几种时间表示:1)时间戳  2)格式化的字符串时间 3)struct_time元组格式的时间 time.datetime模块源码: ...

  3. ql的python学习之路-day13

    前言:本节主要学习模块 一.模块的定义 模块:本质是.py结尾的python文件(文件名:test.py,对应的模块是:test),用来从逻辑上组织python代码(变量.函数.类.逻辑,本质是实现一 ...

  4. ql的python学习之路-day12

    前言:这一节主要学习json和pickle 背景: 相信大家在日常生活中都有接触大型的网络游戏,打游戏的时候都是自己在电脑上操作,自己刷怪升级:当然也会碰到中午去吃饭然后挂机的情况,让电脑自动的刷怪, ...

  5. ql的python学习之路-day11

    前言:本节主要学习python内置的方法 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:qinjiaxi from collections ...

  6. ql的python学习之路-day10

    前言:本节主要讲解迭代器和生成器 迭代器&生成器 一.生成器(generator) 循环占用大部分的容量内存,如果只需要循环前面的几个结果那怎么样做呢,在python中有一种一边循环一边计算的 ...

  7. ql的python学习之路-day8

    前言:本节主要学习的是函数的全局变量和局部变量以及递归 一.全局变量和局部变量 定义在函数外并且在函数头部的变量,叫做全局变量,全局变量在整个代码中都生效. 局部变量只在函数里生效,这个函数就叫做这个 ...

  8. ql的python学习之路-day7

    函数与函数式编程 一.编程模式分为三种: 1.面向对象编程:类----->关键字class 2.面向过程编程:过程----->关键字def,没有return 3.函数式编程:函数----- ...

  9. ql的python学习之路-day6

    字节编码: 这一节主要学习的是各种编码模式的相互转换,另外插两句话,今天的心情不是特别好,又没控制好自己的情绪,以后要心存阳光,好好的对待生活和身边的人. 废话不多说了直接贴码: #!/usr/bin ...

随机推荐

  1. tensorflow1.0 dropout层

    """ Please note, this code is only for python 3+. If you are using python 2+, please ...

  2. DEDE Fatal error: Maximum execution time of 30 seconds exceeded 致命 错误: 最大的 执行 时间 为 30 秒

    刚安的DEDE    5.7 -SP1-GBK的  为何一登录后台点任何链接都显示超过30秒  后台假死 网上搜的方法一般都是更改执行时间上限,其目的是为了解决一些大的数据,真的需要30秒以上的执行时 ...

  3. Iterator to list的三种方法

    目录 简介 使用while 使用ForEachRemaining 使用stream 总结 Iterator to list的三种方法 简介 集合的变量少不了使用Iterator,从集合Iterator ...

  4. 走 进 java 的 四 个 基 本 特 性

    赶上明天就还是五一c小长假了,准备在这几天写几篇原创文章,供大家一起学习. 首先今天就来好好地唠一唠,到底java的那几个特性都是什么呢?到底怎么用呢?相信一定有一些小白对此会有些懊恼,没关系的,谁还 ...

  5. ps 和 top

    ps 进程和线程的关系: (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程. (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源. (3)处理机分给线程,即真正在处 ...

  6. 被@ResponseBoby注释的方法在拦截器的posthandle方法中设置cookie失效的问题

    文章标题可能有点绕口.先来解释下遇到的问题. 我写了一个拦截器,希望能够实现保存特定方法的请求参数到cookie中. public class SaveParamInterceptor extends ...

  7. Cisco 交换机启用netflow

    Router2951#configure terminal //Creating Flow Record router2951(config)# flow record NTArecord route ...

  8. 《WCF技术内幕》翻译3:第1部分_第1章_蓝月亮:普遍需求和普遍概念

    第一部分:WCF介绍    章节目录:    第1章:蓝月亮    第2章:面向服务    第3章:消息交换模式.拓扑和编排    第4章:WCF 101 第1章:蓝月亮    商业和市场对软件系统新 ...

  9. Frame Relay Voice Traffic Shaping and Frament

    本文全称应该是:Frame Relay Voice-Adaptive Traffic Shaping and Fragmentation,标题限制字数,没办法了   帧中继的流量整型向来是个头疼的地方 ...

  10. SSM框架完整开发流程

    ----------------第一阶段-------------- 1.数据库建模 2.生成sql语句 3.在mysq客户端使用命令方式执行sql脚本,生成数据库 4.允许远程访问mysql GRA ...