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之闭包函数、装饰器的更多相关文章

  1. Python作用域-->闭包函数-->装饰器

    1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部 ...

  2. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  3. Python函数编程——闭包和装饰器

    Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...

  4. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  5. python之闭包与装饰器

    python闭包与装饰器 闭包 在函数内部定义的函数包含对外部的作用域,而不是全局作用域名字的引用,这样的函数叫做闭包函数. 示例: #-------------------------------- ...

  6. Python之闭包and装饰器

    闭包和装饰器是Python中非常重要的一种语法格式,在日常工作中应用非常广泛. 首先,我先为大家简单的介绍一下闭包的概念. 闭包:闭包是在函数嵌套的基础上,内层函数使用到外层函数的变量,且外层函数返回 ...

  7. python语法基础-函数-装饰器-长期维护

    ######################################################### # 装饰器 # 装饰器非常重要,面试Python的公司必问, # 原则:开放封闭原则 ...

  8. python 修改的函数装饰器

    把好的代码记录下来 方便以后学习 修改的函数参数装饰器 from functools import wraps import time import logging def warn(timeout) ...

  9. python二 总结--函数-- 装饰器

    装饰器是什么? 有什么用? 为什么要用? 真的有用吗? 1.装饰器: 装饰器: 定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能. 原则:1.不能修改被装饰的函数的源代码          ...

  10. 关于python的闭包与装饰器的实验

    首先看闭包,在嵌套函数内添加返回值,可以通过外部函数读取内部函数信息 #encoding=utf-8 #闭包应用 #先定义闭包函数,并使用 def outer(func): def inner(): ...

随机推荐

  1. SQL server数据库的部署

    一.实验目标 1.安装一台SQL  SERVER(第一台),然后克隆再一台(第二台),一共两台,修改两台的主机和IP地址. 2.使用注册的方式,用第二台远程连接第一台 二.实验步骤 1)先打开一台Wi ...

  2. if a in range(len(lst)): print(a,lst[a]) #获取索引和对应元素, 背下来~~

    经典的"获取元素的索引和元素", 背下来! if a in range(len(lst)): print(a, lst[a])

  3. Spring Boot 以 war 方式部署

    Spring Boot 默认自带了一个嵌入式的 Tomcat 服务器,可以以jar方式运行,更为常见的情况是需要将 Spring Boot 应用打包成一个 war 包,部署到 Tomcat.Jerry ...

  4. 【教程】【FLEX】#005 拖动

    在Flex中,组件的拖动分为: 1. 加强型(即本身就可以拖动设置是否可以拖动的属 [dragEnabled ,dropEnabled ] 即可) 2. 非加强型(可以通过DragManager,Dr ...

  5. APP的案例分析

    很多同学有误解,软件项目管理是否就是理论课?或者是几个牛人拼命写代码,其他人打酱油的课?要不然就是学习一个程序语言,搞一个职业培训的课?都不对,软件项目管理有理论,有实践,更重要的是分析,思辨,总结. ...

  6. 终端复用工具 tmux 基本操作教程

    简介 在 Linux 操作环境下,终端操作是发挥 Linux 强大命令功能的重要途径,但在本地主机操作中,针对不同任务开启不同的终端,在使用时进行频繁的终端切换在某些场合下是一种使人分心和疲惫的操作, ...

  7. 20155314 2016-2017-2 《Java程序设计》第1周学习总结

    20155314 2016-2017-2 <Java程序设计>第1周学习总结 学习目标 了解Java基础知识(已完成) 了解JVM.JRE与JDK,并下载.安装.测试JDK(已完成) 了解 ...

  8. 列表中不限制宽度,hover时,字体font-weight:bold,防止抖动

    项目一个小问题困扰了很久,在一个没有限制宽度的列表容器中,如果给hover时,给字体➕'font-wieght:bold'容器就会变宽,然后移动的下一个容器,就会出现抖动,这样很是影响用户体验,于是在 ...

  9. 使用mongodump及mongorestore备份及恢复数据

    mongodump及mongorestore是用于备份和恢复mongodb数据库的两个命令,位于mongodb安装目录的bin文件夹下. mongodump导出的备份文件为二进制格式,每一个文档的对应 ...

  10. 关于 MFRC522引脚功能图

    MFRC522是属于13.56mhz芯片.另外SI522也是13.56mhz芯片,SI522 PIN对PIN完全兼容MFRC522,并且软硬件兼容,且引脚功能图都是一样的,功能方面比MFRC522多A ...