一.闭包函数

1.闭函数:被封闭起来的函数==>定义在函数内部的函数,特点是只能在函数内调用

2.包函数:该函数引用了一个名字,该名字来自于E这一层

  总结:闭包函数指的是定义在函数内部的函数引用了一个来自于外层函数作用域中的名字

#例如wrapper函数
# def outter():
# x = 100
# def wrapper():
# print(x)

3.闭包函数升级:结合函数对象

# def outter():
# x = 100
# def wrapper():
# print(x)
# return wrapper # 千万不要加括号
#
# f = outter()
#
# print(f)
#
# def foo():
# x = 666
# f()
#
# foo()

4.为函数体传参的两种解决方案

方案一:直接以参数的形式传入

# def wrapper(x):
# print(x)
#
# wrapper(100)

方案二:闭包函数方式 

# def outter(x):
# # x = 100
# def wrapper():
# print(x)
# return wrapper # 千万不要加括号
#
# f = outter(100)
# f()

二.装饰器

1.什么是装饰器

    ’装饰’代指为被装饰对象添加新的功能

    ’器’代指器具/工具

但实现装饰器必须遵循的原则是:开放封闭原则

  开放指的是对拓展新功能是开放的,封闭指的则是对修改源代码以及调用方式是封闭的  

#综上装饰器指的是我们要创建一个工具,该工具可以在遵循原则1和2的前提下还能为被装饰对象添加新功能

        原则1、不修改被装饰对象源代码

        原则2、不修改被装饰对象调用方式

2.为什么要用装饰器

软件包含的所有功能的源代码以及调用方式,都应该避免修改,否则一旦改错,则极有可能产生连锁反应,最终导致程序崩溃,而对于上线后的软件,新需求或者变化又层出不穷,我们必须为程序提供扩展的可能性,这就用到了装饰器。

3.用法

**装饰器的推导**

# 被装饰者:给被装饰者添加新功能
# import time
#
# def index():
# print('from index')
# time.sleep(3)
#
# index() # 方案一:改变被装饰者的源代码
# import time
#
# def index():
# start = time.time()
# print('from index')
# time.sleep(1)
# end = time.time()
# print('run time is %s' %(end - start))
#
# index() # # 方案二:装饰器的功能需要重复编写,代码冗余
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
#
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
# # # 方案三:解决方案二的代码冗余问题,但是存在问题-》装饰器的功能写死了,只能装饰index函数
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# def wrapper():
# start = time.time()
# index()
# end = time.time()
# print('run time is %s' %(end - start))
#
# wrapper()
# wrapper() # # 方案四:装饰器的功能写活
# import time
#
# def index():
# print('from index')
# time.sleep(1)
#
# def outter(func):
# # func = index
# def wrapper():
# start = time.time()
# func()
# end = time.time()
# print('run time is %s' %(end - start))
# return wrapper
#
# index = outter(index) # index = wrapper的内存地址
# # print(index)
# index() # 方案五:装饰器的功能写活
import time def index():
print('from index')
time.sleep(1) def home(name):
print('welcome %s to home page' % name)
time.sleep(0.5)
return 123 def outter(func):
# func = 最原始那个home的内存地址
def wrapper(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs) # 最原始那个home的内存地址()
end = time.time()
print('run time is %s' % (end - start))
return res
return wrapper home = outter(home) # home = wrapper的内存地址
index = outter(index) # home = wrapper的内存地址 res = home('egon')
print(res) # res = index()
# print(res)

**装饰器语法糖**(简化)

import time

def outter(func):
# func = 最原始那个home的内存地址
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs) # 最原始那个home的内存地址()
end = time.time()
print('run time is %s' % (end - start))
return res return wrapper @outter # index = outter(index)
def index():
print('from index')
time.sleep(1) @outter # home = outter(home)
def home(name):
print('welcome %s to home page' % name)
time.sleep(0.5)
return 123 res = home('lzl')
print(res)

**多个装饰器叠加**

# 装饰器模板
# def deco(func):
# def wrapper(*args,**kwargs):
# res = func(*args,**kwargs)
# return res
# return wrapper # 统计时间的装饰器
# import time
#
# def timmer(func):
# def wrapper(*args,**kwargs):
# start = time.time()
# res = func(*args,**kwargs)
# stop = time.time()
# print(stop - start)
# return res
# return wrapper # 认证功能装饰器
# def auth(func):
# def wrapper(*args,**kwargs):
# inp_user = input('Username: ').strip()
# inp_pwd = input('Password: ').strip()
# if inp_user == 'egon' and inp_pwd == '123':
# res = func(*args,**kwargs)
# return res
# else:
# print('登录失败')
# return wrapper
#
# @auth # index = auth(index)
# def index():
# print('from index')
#
# index() """
def deco1(func1): # func1 = wrapper2的内存地址
def wrapper1(*args,**kwargs):
print('===>wrapper1')
res1 = func1(*args,**kwargs)
print('=====>end wrapper1')
return res1
return wrapper1 def deco2(func2): # func2 = wrapper3的内存地址
def wrapper2(*args,**kwargs):
print('===>wrapper2')
res2 = func2(*args,**kwargs)
print('=====>end wrapper2')
return res2
return wrapper2 def deco3(func3): # func3 = 最原始那个index的内存地址
def wrapper3(*args,**kwargs):
print('===>wrapper3')
res3 = func3(*args,**kwargs)
print('=====>end wrapper3')
return res3
return wrapper3 # index = wrapper1的内存地址
@deco1 # deco1(wrapper2的内存地址) ---> wrapper1的内存地址
@deco2 # deco2(wrapper3的内存地址) ---> wrapper2的内存地址
@deco3 # deco3(最原始那个index的内存地址) ---> wrapper3的内存地址
def index():
print('=======>index') index()
""" # print(index) import time def timmer(func):
def wrapper1(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
stop = time.time()
print(stop - start)
return res
return wrapper1 def auth(func):
def wrapper2(*args,**kwargs):
inp_user = input('Username: ').strip()
inp_pwd = input('Password: ').strip()
if inp_user == 'egon' and inp_pwd == '123':
res = func(*args,**kwargs)
return res
else:
print('登录失败')
return wrapper2 @auth
@timmer
def index():
print('====>index')
time.sleep(3)
index()

 有参装饰器:

def outter2(mode,yyy):
# mode = 'mysql'
def outter(func): # func = index
def wrapper(*args ,**kwargs):
print(yyy)
inp_user = input('Username: ').strip()
inp_pwd = input('Password: ').strip()
if mode == 'file':
if inp_user == "egon" and inp_pwd == "123":
res = func(*args ,**kwargs)
return res
else:
print('login failed')
elif mode == 'mysql':
print("基于mysql数据库的认证")
elif mode == 'ldap':
print("基于ldap数据库的认证")
else:
print('未知的认证来源')
return wrapper
return outter @outter2('mysql',111) # @outter # index = outter(index) # index = wrapper
def index():
print('from index') @outter2('ldap',222)
def home(name):
print('hello %s' %name)

 ###functools模块下提供一个装饰器wraps专门用来保留原函数属性####

4.总结

1、无参装饰器模板

# def outter(func):
# def wrapper(*args,**kwargs):
# res = func(*args,**kwargs)
# return res
# return wrapper
#
# @outter
# def index():
# pass

2、有参装饰器模板

def outter2(xxx):
def outter(func):
def wrapper(*args,**kwargs):
xxx
res = func(*args,**kwargs)
return res
return wrapper
return outter @outter2(xxx=111)
def index():
pass

  

 

day10.闭包函数与装饰器的更多相关文章

  1. day11 闭包函数和装饰器

    1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...

  2. python基础-闭包函数和装饰器

    闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...

  3. Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器

    目录 一 函数对象 二 函数的嵌套 三 名称空间和作用域 四 闭合函数 五 装饰器 一.函数对象 1.函数是第一类对象 #第一类对象的特性:# 可以被引用 # 可以当做参数传递 # 返回值是函数 # ...

  4. 【Python3的命名空间与作用域,闭包函数,装饰器】

    一.命名空间与作用域 命名空间是名字和对象的映射,就像是字典,key是变量名,value是变量的值 1.命名空间的定义 name='egon' #定义变量 def func(): #定义函数 pass ...

  5. day11_7.11 闭包函数与装饰器

    补充: callable 代表可调用的,加括号可以执行.(函数或者类) import this  查看python之禅 一.闭包函数 所谓闭包函数,就是定义在函数内部的函数,也就是函数定义的嵌套.而在 ...

  6. CSIC_716_20191112【闭包函数和装饰器】

    闭包函数 什么是闭包函数:闭包函数是函数嵌套.函数对象.名称空间和作用域的集合体. 闭包函数必须在函数内部定义,闭包函数可以引用外层函数的名字. # _*_ coding: gbk _*_ # @Au ...

  7. Python--day13(函数嵌套定义,global、nonlocal、闭包函数、装饰器)

    今日主要内容 1.  函数的嵌套定义 2.  global.nonlocal关键字 3.  闭包及闭包的应用场景 4. 装饰器 1.  函数的嵌套定义 概念:在一个函数的内部定义另一个函数 为什么要有 ...

  8. python---基础知识回顾(二)(闭包函数和装饰器)

    一.闭包函数: 闭包函数: 1.在一个外函数中定义了一个内函数 2.内函数里运用了外函数的临时变量,而不是全局变量 3.并且外函数的返回值是内函数的引用.(函数名,内存块地址,函数名指针..) 正确形 ...

  9. Python之闭包函数、装饰器

    1.闭包函数 #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关 # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1(): # x=1 # def inner(): ...

随机推荐

  1. 【springboot读取配置文件】@ConfigurationProperties、@PropertySource和@Value

    概念: @ConfigurationProperties : 是springboot的注解,用于把主配置文件中配置属性设置到对于的Bean属性上 @PropertySource :是spring的注解 ...

  2. django 内置“信号”机制和自定义方法

    一.引子 在操作数据的时候,假设我们需要记录一些日志,这个时候,我们需要用什么来显示这个需求呢?装饰器?装饰器只能先实现整体的操作.在django 里面有这么一个东西--信号 下面我们就来了解了解它. ...

  3. Pycharm模块导入失败,带有红色波浪线。

    在Pycharm中打开一个python开源工程,结果在导入库的部分一堆红色波浪线显示错误,并且按住Ctrl + 鼠标左击无法跳转到指定类或方法,如下图所示. 解决方法: (1)首先忽略掉这些报错,先运 ...

  4. ElasticSearch 集群的规划部署与运维

    公号:码农充电站pro 主页:https://codeshellme.github.io 1,常见的集群部署方式 ES 有以下不同类型的节点: Master(eligible)节点:只有 Master ...

  5. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  6. CCF(消息传递口:80分):字符串相关+队列

    消息传递口 201903-4 本题主要是利用队列进行模拟,因为一开始我没有注意到要按照顺序,所以一开始的解法错误. #include<iostream> #include<algor ...

  7. HDOJ-6641(欧几里得+异或运算)

    TDL HDOJ-6641 关于题意,就是要找出符合f的第m大的数,而且后面还要满足异或等式. 通过观察题目,可以发现n太大了,所以不能直接枚举.当然因为m比较小,所以可以转换思路k^n,这个数最大不 ...

  8. (数据科学学习手札110)Python+Dash快速web应用开发——静态部件篇(下)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  9. python3 获取博彩网站页面下所有域名(批量)

    已有的域名信息 详细实现过程如下 #!/usr/bin/env python # -*- coding:utf-8 -*- import requests from bs4 import Beauti ...

  10. Python接口自动化实现

    一.代码结构: 二.接口签名实现: 1. 设所有发送的数据集合为M,将集合M内非空参数值的参数按照[参数名+"="+参数值]的ASCII码从小到大排序(字典序),然后按拼接key1 ...