Python之闭包函数、装饰器
1、闭包函数
#作用域关系在函数定义阶段时就已经固定死了,与调用位置无关
# 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1():
# x=1
# def inner():
# print(x) #闭包的含义:内部函数中的变量x引用外部作用域的x,而非全局作用域的x
# return inner
# func=f1() #f1()=inner
#
#
# def f2():
# x=111111
# func() #func()=inner()
# f2() # 闭包函数:
# 闭指的是:该函数是一个内部函数
# 包指的是:指的是该函数包含对外部作用域(非全局作用域)名字的引用
# def outter():
# x = 1
# def inner():
# print(x) #内部函数inner中的x是对外部作用域的引用,而非全局作用域的引用
#
# return inner
#
# f=outter()
#
# def f2():
# x=1111111
# f()
#
# f2()
#
#
# def f3():
# x=4444444444444
# f()
#
# f3() # 为函数传值的两种方式:
# 为函数体传值的方式一:使用参数的形式
# def inner(x):
# print(x)
#
# inner(1)
# inner(1)
# inner(1) # 为函数体传值的方式二:包给函数
'''
def outter(x):
# x=1
def inner():
print(x) #通过闭包函数将值报给内部函数
return inner f=outter(1)
f()
''' # 例子:
# 方法一:通过传参的形式将值传给函数内的变量
# import requests
# def get(url):
# response=requests.get(url)
# if response.status_code == 200:
# print(response.text)
#
# get('https://www.baidu.com')
# get('https://www.baidu.com')
# get('https://www.baidu.com')
#
# get('https://www.python.org')
# get('https://www.python.org')
# get('https://www.python.org')
# get('https://www.python.org') # 方法二:通过闭包函数将值包给其内部的函数
import requests
def outter(url): #通过传参的形式,可以爬去任意网页的源代码
# url='https://www.baidu.com' #功能被写死,所以改成传参的形式
def get():
response=requests.get(url) #url是通过outter函数,将值包给函数get内的函数体代码用的
if response.status_code == 200: #成立说明,成功爬去网页的源代码
print(response.text)
return get #返回get给外部的调用者,打破层级的限制(函数对象的知识) baidu=outter('https://www.baidu.com') #本质就是传入了参数的get的内存地址
python=outter('https://www.python.org') baidu() #本质就是已经给url传入了参数的get的内存地址,加括号即调用
baidu() python()
python()
2、装饰器
'''
1、什么是装饰器
器指的是工具,而程序中的函数就具备某一功能的工具
装饰指的是为被装饰器对象添加额外功能 就目前的知识来看:
定义装饰器就是定义一个函数,只不过该函数的功能是用来为
其他函数添加额外的功能 其实:
装饰器本身其实可以是任意可调用的对象
被装饰的对象也可以是任意可调用的对象 2、为什么要用装饰器
软件的维护应该遵循开放封闭原则
开放封闭原则指的是:
软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的
这就用到了装饰器 装饰器的实现必须遵循两大原则:
1、不修改被装饰对象的源代码
2、不修改被装饰对象的调用方式
装饰器其实就在遵循1和2原则的前提下为被装饰对象添加新功能 3、如何用装饰器
''' # 方式一
# 给原函数添加上了新功能,没有改变原函数的调用方式,但是却改变了源代码
import time
# def index():
# start=time.time()
# print('welcom to index')
# time.sleep(3)
# stop=time.time()
# print('run time is %s' %(stop-start))
# index() # 方法二
# 没有改变源代码,也没有改变调用方式,但是给不同函数扩展相同的功能时,是在重复写代码的过程
import time
# def index():
# print('welcom to index')
# time.sleep(3)
#
# def f2():
# print('from f2')
# time.sleep(2) # 以下为两个函数添加上了引得功能,但是重复写代码
# start=time.time()
# index()
# stop=time.time()
# print('run time is %s' %(stop-start))
# #
# start=time.time()
# f2()
# stop=time.time()
# print('run time is %s' %(stop-start)) # 方法三
# 将重复写代码的过程,定义为一个函数的功能,虽然没有该源代码,但是改变了函数的调用方式
# import time
#
# def index():
# print('welcom to index')
# time.sleep(3)
#
# def timmer(func):
# start=time.time()
# func()
# stop=time.time()
# print('run time is %s' %(stop-start))
#
# timmer(index) # 方法四
# 利用闭包函数,为函数添加上新的功能 '''
import time
def index():
print('welcom to index')
time.sleep(3) def timmer(func): #func=最原始的index
# func=index #这样就把被装饰的对象写死了,所以需要以传参的形式将,被装饰的函数传进来
def inner():
start=time.time()
func()
stop=time.time()
print('run time is %s' %(stop-start))
return inner # f=timmer(index)
# f() # index=timmer(被装饰函数的内存地址)
index=timmer(index) #index=inner index() #inner() '''
import time def index():
print('welcom to index')
time.sleep(3) def timmer(func): #将被装饰的函数传进来,不至于将被装饰的对象写死,固定是某一个,而是可以装饰任意一个函数
#func=最原始的index ,即被装饰函数的的内存地址
def wrapper(): #该函数即是为被装饰函数添加上的新功能
start=time.time()
func() #最原始的index加括号即使调用最原始的函数
stop=time.time()
print('run time is %s' %(stop - start))
return wrapper #函数对象知识:返回给外部函数调用,打破层级限制 index=timmer(index) #左边的index=wrapper函数的内存地址,右边的index即是我们要装饰的函数
index() #本质调用的是wrapper函数
三、装饰器修正
import time
def index(): #被装饰的函数无参,有返回值
print('welcome to index')
time.sleep(3)
return 123 def home(name): #被装饰的函数有参,没有返回值
print('welcome %s to home page' %name)
time.sleep(2) def timmer(func):
#func=最原始的index
def wrapper(*args,**kwargs): #wrapper会将接收的参数,原封不动的传给被装饰的函数
start=time.time()
res=func(*args,**kwargs) #因为被装饰的对象可能有的有参,有的是无惨,所以调用时用*args,**kwargs,无论有无参数都不会报错
stop=time.time()
print('run time is %s' %(stop - start))
return res #接收被装饰函数的返回值,被装饰的函数没有返回值则为None,有则返回被装饰的返回值
return wrapper #该返回值则是返回给外部函数用的,可以打破层级的限制,这样内部函数即给被装饰函数添加的新功能就可以被调用到 index=timmer(index) #将被装饰的函数传入,调用装饰器,本质就是调内部被加上新功能的函数
home=timmer(home) #将被装饰的函数传入,调用装饰器,本质就是调内部被加上新功能的函数 res=index() #拿到调用函数的返回值,打印即可看到返回值
home('egon') #被装饰的函数为有参,为被装饰函数进行传参
print(res) #装饰器语法糖
# 在被装饰对象正上方,并且是单独一行写上@装饰器名
# import time
# def timmer(func):
# #func=最原始的index
# def wrapper(*args,**kwargs):
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print('run time is %s' %(stop - start))
# return res
# return wrapper
#
# @timmer # index=timmer(index) #timmer即一个名字,所以装饰器的代码块要写在timmer的上方,@timmer本质就是调用了timmer(传入被装饰的函数名)
# def index():
# print('welcome to index')
# time.sleep(3)
# return 123
#
# @timmer # home=timmer(home)
# def home(name):
# print('welcome %s to home page' %name)
# time.sleep(2)
#
# res=index()
# home('egon') # 装饰器的万能模板:
def deco(func): #func即是要接收的被砖石的函数名
def wrapper(*args,**kwargs): #可以根据被装饰的函数需不需要传参,给被装饰的对象传入参数
res=func(*args,**kwargs) #本质就是调用被装饰的函数, 接收传进来的参数
return res #接收被装饰函数的返回值,没有则返回None
return wrapper #外部函数将内部函数的内存地址返回,打破层级限制
Python之闭包函数、装饰器的更多相关文章
- Python作用域-->闭包函数-->装饰器
1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部 ...
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- Python函数编程——闭包和装饰器
Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- python之闭包与装饰器
python闭包与装饰器 闭包 在函数内部定义的函数包含对外部的作用域,而不是全局作用域名字的引用,这样的函数叫做闭包函数. 示例: #-------------------------------- ...
- Python之闭包and装饰器
闭包和装饰器是Python中非常重要的一种语法格式,在日常工作中应用非常广泛. 首先,我先为大家简单的介绍一下闭包的概念. 闭包:闭包是在函数嵌套的基础上,内层函数使用到外层函数的变量,且外层函数返回 ...
- python语法基础-函数-装饰器-长期维护
######################################################### # 装饰器 # 装饰器非常重要,面试Python的公司必问, # 原则:开放封闭原则 ...
- python 修改的函数装饰器
把好的代码记录下来 方便以后学习 修改的函数参数装饰器 from functools import wraps import time import logging def warn(timeout) ...
- python二 总结--函数-- 装饰器
装饰器是什么? 有什么用? 为什么要用? 真的有用吗? 1.装饰器: 装饰器: 定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能. 原则:1.不能修改被装饰的函数的源代码 ...
- 关于python的闭包与装饰器的实验
首先看闭包,在嵌套函数内添加返回值,可以通过外部函数读取内部函数信息 #encoding=utf-8 #闭包应用 #先定义闭包函数,并使用 def outer(func): def inner(): ...
随机推荐
- 【Excel】坐下,VLOOKUP基本操作
坐下,VLOOKUP基本操作 VLOOKUP如何使用我就不在这里详细介绍了,简单说一下好了. 如上图,第一个填写你要查找的值,第二个空选取你查找的范围,第三个空填你要得到第几列的值,最后选 ...
- SDN 第一次作业
你会选择作 网络编程 方向的程序员吗?为什么? 答: 可能会选择吧.看了那篇文章感觉网络编程的程序员和其他的程序员都并不简单,网络编程的程序员可能更要对网络的知识更加了解.我现在也有机会能接触网络方向 ...
- postGresql关键字字段重名
在postGresql中如果关键字和自定义的字段重名 即使使用[ ](中括号)或者 ' '(单引号)都没有用,经本人实验. 如果使用" "(双引号),则可以.
- JavaScript设计模式—工厂模式
工厂模式介绍 将new操作符单独进行封装,遇到new时,就要考虑是否该使用工厂模式 举一个生活当中的示例: 你要去购买汉堡,直接点餐,取餐,不会自己动手做,商店要“封装” 做汉堡的工作,做好直接给购买 ...
- Spring-IOC MethodInvokingFactoryBean 类源码解析
MethodInvokingFactoryBean MethodInvokingFactoryBean的作用是,通过定义类和它的方法,然后生成的bean是这个方法的返回值,即可以注入方法返回值. Me ...
- P4053 [JSOI2007]建筑抢修
题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建 ...
- 【node.js】Stream(流)
Stream 有四种流类型: Readable - 可读操作. Writable - 可写操作. Duplex - 可读可写操作. Transform - 操作被写入数据,然后读出结果. 所有的 St ...
- Sequelize-nodejs-9-Scopes
Scopes作用域 Scoping allows you to define commonly used queries that you can easily use later. Scopes c ...
- crontab定时执行
一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cro ...
- python file的3中读法
f.read() 整个文件读入到内存,全部放入到一个string中 f.readlines() 文件全部内容解析成行列表,自带\n,需要print i, f.readline()一行一行,返回字符串 ...