目录

函数对象 :相当于变量名

函数对象的作用:

1. 可以引用

def f1():
print("from f1") a = f1
a() '''
from f1 '''

2. 可以作为函数的返回值

def f1():
print("from f1") def f2():
return f1 a = f2()
a() '''
from f1
'''

3. 可以作为容器的元素

def f1():
print("from f1")
a = [1,2,3,4,5,f1]

4. 可以作为函数的参数

def f1():
print("from f1") def f2(func):
func() f2(f1) '''
from f1
'''

闭包

定义:

如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。那闭包就是,在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包

ps:

一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给内部函数,然后自己结束。

闭包的意义:

返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得该函数无论在何处调用,优先使用自己外层包裹的作用域

# 闭包
def test_plf(x):
def test_lt():
print(x)
return test_lt f1 = test_plf(8)
f1() # 闭包的应用
import requests
def req(url):
def test_plf():
request = requests.get(url)
data = request.status_code
print(data)
return test_plf baidu = req("https://www.baidu.com")
baidu()
baidu()
baidu()
boke = req("https://www.cnblogs.com/plf-Jack/")
boke()
boke()
boke() # 使用普通函数进行对比
import requests
def req(url):
content = requests.get(url)
data = content.status_code
print(data) req("https://www.baidu.com")
req("https://www.baidu.com")
req("https://www.baidu.com")
req("https://www.cnblogs.com/plf-Jack/")
req("https://www.cnblogs.com/plf-Jack/")
req("https://www.cnblogs.com/plf-Jack/") '''
总结:
相比使用普通函数和使用闭包函数实现相同业务逻辑
1. 闭包在调用上要比普通函数要简单
2. 闭包相对于普通函数的定义,逻辑上难度要大一些
3. 闭包主要应用于延迟计算,爬虫领域
'''

装饰器

本质:装饰器 = 函数。它的本质就是函数

作用:给原函数增加新的功能

原则:

1. 不能改变被装饰的函数的调用方式

2. 装饰器不能修改装饰函数的源代码

实现装饰器的知识储备:

1. 函数即“变量”

2. 高阶函数。即一个函数可以作为另外一个函数的参数,这种函数就称之为高阶函数。

3. 嵌套函数。即定义一个函数时,在其函数体中又定义了一个函数,这个函数称之为嵌套函数。

装饰器的模板语法

def deco(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
  1. 无参装饰器

    import time
    def test_lt(func):
    def warpper():
    start_time = time.time()
    func()
    end_time = time.time()
    print("你睡了%s秒"%(end_time-start_time))
    return warpper @test_lt # 语法糖,即简洁。它等同于 test_plf = test_lt(test_plf)
    def test_plf():
    time.sleep(1)
    print("我睡了多长时间")
  2. 返回值装饰器

    import time
    
    def test_lt(func):
    def warpper():
    start_time = time.time()
    res = func()
    end_time = time.time()
    print("睡了%s秒"%(end_time-start_time))
    return res
    return warpper @test_lt #test_plf = test_lt(test_plf)
    def test_plf():
    time.sleep(1)
    print("我睡了多长时间")
    return 123 a = test_plf()
    print("返回值为%d"%a)
  3. 有参装饰器

    dic = {"PLF":'123'}
    is_login = False
    def auth(test_type='file'):
    def login_desc(func):
    def wrepper():
    if test_type == "file":
    global is_login # 声明的是全局变量的is_login
    if not is_login:
    user_name = input("请输入账号>>>")
    user_pwd = input("请输入密码>>>")
    if dic.get(user_name) != user_pwd:
    print("输入错误")
    return
    print("密码输入正确")
    is_login = True
    func()
    return
    func()
    elif test_type == "txt":
    print("文件类型不正确")
    else:
    print("你走开")
    return wrepper
    return login_desc @auth(test_type="file")
    def go_shopping():
    print("购物") @auth(test_type="txt")
    def pay():
    print("支付") @auth(test_type="makeDown")
    def see_list():
    print("查看清单") go_shopping()
    pay()
    see_list()

装饰器的弊端:

import time

def test_lt(func):
def warpper():
start_time = time.time()
res = func()
end_time = time.time()
print("睡了%s秒"%(end_time-start_time))
return res
return warpper @test_lt #test_plf = test_lt(test_plf)
def test_plf():
time.sleep(1)
print("我睡了多长时间")
return 123 print(test_plf.__name__) '''
warpper
''' '''
总结:
1. 目标函数(test_plf)是一个函数对象,它里米那有自己的属性,如函数名__name__,说明文档__doc__等等。但如果目标函数被装饰器装饰之后,我们在调用目标函数的__name__会发现,本来我们想要的test_plf名字,结果打印出来了warpper。这种情况确实不出乎意料,因为test_plf被装饰之后确实存的就是warpper了,我们对test_plf的操作实际上都是对inner的操作.
2. 以上的操作带来了使用的不一致性。如果我们能把本来目标函数各种方法覆盖给test_plf函数就好了。这里我们可以用functools包里的工具来实现。这里暂不做解释,有兴趣的同学先去百度一下。
'''

参考博客:https://www.cnblogs.com/Lin-Yi/p/7306235.html

python之闭包,装饰器的更多相关文章

  1. python函数闭包-装饰器-03

    可调用对象 callable()  # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即  callable(对象)  返回为  True  的对象 x = 1 print(cal ...

  2. 【Python】 闭包&装饰器

    python中的函数本身就是对象,所以可以作为参数拿来传递.同时其允许函数的层级嵌套定义,使得灵活性大大增加. 闭包 闭包的定义:将函数的语句块与其运行所需要的环境打包到一起,得到的就是闭包对象.比如 ...

  3. python高级-闭包-装饰器

    闭包内容: 匿名函数:能够完成简单的功能,传递这个函数的引用,只有功能 普通函数:能够完成复杂的功能,传递这个函数的引用,只有功能 闭包:能够完成较为复杂的功能,传递这个闭包中的函数以及数据,因此传递 ...

  4. python之闭包+装饰器

    闭包 内部函数对外部函数作用域变量的引用. 函数内的属性都是有生命周期的,都是在函数执行期间 闭包内的闭包函数私有化了变量,类似于面向对象 图片解析 示例一 https://www.bilibili. ...

  5. python高级之装饰器

    python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...

  6. Python深入05 装饰器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法 ...

  7. Day04 - Python 迭代器、装饰器、软件开发规范

    1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...

  8. 第二篇:python高级之装饰器

    python高级之装饰器   python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...

  9. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  10. python学习之装饰器-

    python的装饰器 2018-02-26 在了解python的装饰器之前我们得了解python的高阶函数 python的高阶函数我们能返回一个函数名并且能将函数名作为参数传递 def outer() ...

随机推荐

  1. NPC脚本界面自定义美化参数说明

    觉得NPC对话界面太单调了 可以自己定义: 在[@main]下面加上 #ACT OPENMERCHANTBIGDLG  参数(WIL文件序号 图片序号 是否可以移动(0,1) 显示位置(0=左上角,1 ...

  2. C语言:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动。-使字符串的前导*号不得多于n个,若多余n个,则删除多余的*号,

    //fun函数:从p所指字符串中找出ASCII码最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动. #include <stdio.h> void fun( char * ...

  3. LeetCode练题——88. Merge Sorted Array

    1.题目 88. Merge Sorted Array——Easy Given two sorted integer arrays nums1 and nums2, merge nums2 into  ...

  4. python学习HTML之CSS(2)

    1.边框的属性设置 PS:边框的高度和宽度可以采用百分比,但是高度方向的百分比基本无用,因为基数没定,参考没意义!! 2.内边距和外边距 3.在右下角添加一个“回顶部”的标签. <div> ...

  5. Cisco AP-Regulatory Domain

    这一note主要解释Regulatory Domain是什么.以较新的思科AP的型号举例,思科AP的PID一般都是按照如下的命名: AIR-AP3802I-H-K9C 按照自己的理解: AIR:其中的 ...

  6. 【Java excel】导出excel文件

    TestExprot package excel; import java.io.File; import java.io.IOException; import java.text.DateForm ...

  7. php环境一键升级脚本

    因为要解析PHP页面需要配置相应的PHP环境,而系统本身的php版本又大多不合适.网上那种一键lamp和lnmp的脚本很多,但是这样一来自己能够定制的空间则少了.所以我自己编写了个门用于安装php环境 ...

  8. ES 创建mapping

    mapping的写入与查看首先创建一个索引: curl -XPUT "http://erp2.es.kd1.pagoda.com.cn:80/erp_stock_index"{&q ...

  9. Dire Wolf HDU - 5115

    题目链接 一开始很自然的想到了贪心,跑了一下贪心,发现无法处理某一段已经被选走的情况,根据数据范围,区间dp比较适合,能储存区间取样信息 设dp[i][j]为已经杀死区间[i,j]的最小值,可以得到转 ...

  10. golang的io.copy使用

    net/http 下载 在golang中,如果我们要下载一个文件,最简单的就是先用http.get()方法创建一个远程的请求后,后面可使用ioutil.WriteFile()等将请求内容直接写到文件中 ...