闭包函数、无参装饰器

闭包函数:函数内部定义函数,成为内部函数。该内部函数包含对外部作用域,而不是对全局作用域名字的引用,那么该内部函数成为闭包函数。

name=‘alex‘     #定义全局变量name=‘alex‘
def func():
    name=‘egon‘  #定义局部变量name=‘egon‘
    def bar():
        print(name)
    return bar    #返回bar函数名

b=func()    #执行func()结果为bar的函数名  相当于b=bar
name=‘haha‘  #重新定义全局变量name=‘haha‘
print(b)    #打印bar
b()       #执行bar(),name=‘egon‘
执行结果:
<function func.<locals>.bar at 0x000000000222BAE8>
egon 

def func():
    name=‘egon‘
    x=1000000000000000000000
    def bar():
        print(name)
        print(x)
    return bar
f=func()
print(f.__closure__)    #打印出闭包函数外层作用域的变量
print(f.__closure__[0].cell_contents)  #打印出闭包函数外层作用域的第一个变量的值
print(f.__closure__[1].cell_contents)  #打印出闭包函数外层作用域的第一个变量的值
运行结果:
(<cell at 0x0000000001E16528: str object at 0x0000000001E993B0>, <cell at 0x0000000001E16558: int object at 0x0000000001EA3C10>)
egon
1000000000000000000000

闭包函数:1 内部函数 2 包含对外部作用域而非全局作用域的引用
闭包函数的特点:
    自带作用域
    延迟计算

以上两个实例都是包一层,闭包函数可以包多层:

#包两层的闭包函数
def func():
    name=‘egon‘     #第2层作用域的变量
    def wrapper():
        money=1000      #第1层作用域的变量
        def tell_info():
            print(‘my namn is %s‘ % name)   #使用第2层作用域的变量
            print(‘egon have money %s‘ %(money))    #使用第1层作用域的变量
        print(tell_info.__closure__)        #打印闭包函数的变量
        return tell_info
    return wrapper
w=func()
tell_info=w()
print(tell_info.__closure__[0].cell_contents)  #闭包函数变量位置在定义时就定下来了,不因为使用的顺序变化
print(tell_info.__closure__[1].cell_contents)
运行结果:
(<cell at 0x0000000001E16558: int object at 0x000000000048AED0>, <cell at 0x0000000001E16528: str object at 0x0000000001E993B0>)
1000
egon

定义闭包函数的基本形式:

def 外部函数名():
    内部函数需要的变量
    def 内部函数():
        引用外部变量
    return 内部函数

def deco():
    x=1
    def wrapper():
        print(x)
    return wrapper

wrapper=deco()
print(wrapper)

#包两层
def deco1():
    y=2
    def deco():
        x=1
        def wrapper():
            print(x)
            print(y)

        return wrapper
    return deco
deco=deco1()
wrapper=deco()
wrapper()

二、无参装饰器

1、开放封闭原则,对扩展是开放的,对修改是封闭的

2、装饰器,装饰器本质可以任意可调用对象,被装饰的对象也可以是任意
可调用对象,
装饰器的功能是:
在不修改被装饰对象源代码以及调用方式的前提下为期添加新功能

原则:
1.不修改源代码
2.不修改调用方法
目标:添加新功能

无参装饰器=高级函数+函数嵌套

基本框架

#这就是一个实现一个装饰器最基本的架子
def timer(func):
    def wrapper():
        func()
    return wrapper

加上参数

def timer(func):
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
    return wrapper

加上功能

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print(‘函数[%s],运行时间是[%s]‘ %(func.__name__,stop_time-start_time))
    return wrapper

加上返回值

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(‘函数[%s],运行时间是[%s]‘ %(func.__name__,stop_time-start_time))
        return res
    return wrapper

使用装饰器的方法一:

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(‘函数[%s],运行时间是[%s]‘ %(func.__name__,stop_time-start_time))
        return res
    return wrapper

def cal(array):
    res=0
    for i in array:
        res+=i
    return res

cal=timer(cal)
cal(range(100000))

运行结果:
函数[cal],运行时间是[0.0070002079010009766]

使用@装饰器名称的方法:

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(‘函数[%s],运行时间是[%s]‘ %(func.__name__,stop_time-start_time))
        return res
    return wrapper
@timer
def cal(array):
    res=0
    for i in array:
        res+=i
    return res

cal(range(100000))
函数[cal],运行时间是[0.007000446319580078]

上课实例:

#装饰器修订
import time
import random
#装饰器
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print(‘run time is %s‘ %(stop_time-start_time))
        return res
    return wrapper
#被装饰函数

@timmer
def index():
    time.sleep(random.randrange(1,5))
    print(‘welecome to index page‘)
@timmer
def home(name):
    time.sleep(random.randrange(1,3))
    print(‘welecome to %s HOME page‘ %name)
    return 1231231231

index()

res1=index()
print(‘index return %s‘ %res1)
res2=home(‘egon‘) #wraper()
print(‘home return %s‘ %res2)

运行结果:
welecome to index page
run time is 2.0001144409179688
welecome to index page
run time is 3.001171350479126
index return None
welecome to egon HOME page
run time is 1.0000574588775635
home return 1231231231

时间: 2024-10-15 15:01:16

闭包函数、无参装饰器的相关文章

闭包函数、无参装饰器2

一.闭包函数 闭包函数:函数内部定义函数,成为内部函数.该内部函数包含对外部作用域,而不是对全局作用域名字的引用,那么该内部函数成为闭包函数. name='alex' #定义全局变量name='alex' def func(): name='egon' #定义局部变量name='egon' def bar(): print(name) return bar #返回bar函数名 b=func() #执行func()结果为bar的函数名 相当于b=bar name='haha' #重新定义全局变量n

无参装饰器为被装饰函数添加统计时间的功能

#需求 定义无参装饰器为被装饰函数添加统计时间的功能 1 import time #导入时间模块 2 3 def timer(func): 4 def wapper(): 5 start = time.time() 6 func() 7 stop = time.time() 8 index_spend_time = stop - start 9 print(index_spend_time) 10 return wapper 11 @timer 12 def index(): 13 time.s

ⅩⅥ:无参装饰器

一:储备知识 1.*args, **kwargs def index(x,y): print(x,y) def wrapper(*args,**kwargs): index(*args,**kwargs) # # index(y=222,x=111) wrapper(y=222,x=111) 2.名称空间与作用域:名称空间的的"嵌套"关系是在函数定义阶段,即检测语法的时候确定的 3.函数对象: # 可以把函数当做参数传入 # 可以把函数当做返回值返回 def index(): retu

无参装饰器

#这就是一个实现一个装饰器最基本的架子#无参装饰器=高级函数+函数嵌套def time(func): def wrapper(): func() return wrapper#加上参数 def time(func): def wrapper(*args,**kwargs): func(*args,**kwargs) return wrapper #加上功能 import timedef timer(func): def wrapper(*args,**kwargs): start_time=ti

python中的无参装饰器和有参装饰器

python中的无参装饰器和有参装饰器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 装饰器特点: 1>.开放封闭原则,即对扩展是开放的,对修改时封闭的: 2>.装饰器本质可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象: 3>.装饰器的功能是在不修改被装饰器对象源代码以及被装饰器对象的调用方式的前提下为其扩展新功能: 4>.装饰器本质是函数,(即装饰其他函数)就是为其他函数添加附加功能. 一.典型装饰器案例 1 #!/usr/bin/env pyth

17、无参装饰器

一.什么是装饰器 器是工具,这里指的是函数 装饰指的是添加额外的东西 所有装饰器的意思就是给定义好的函数添加上额外的功能 二.为什么要用装饰器 装饰器的目的是在不修改源代码以及调用方式的前提下为装饰对象添加新的功能 三.装饰器的原则 开放封闭式原则 开放指的是扩展功能是开放的 封闭指的是对源代码修改是封闭的 四.怎么使用装饰器 1.例题:先设定一个基本函数 def index(x,y): time.sleep(3) print('index %s %s' %(x,y)) 2.在函数的基础上添加运

函数嵌套与装饰器

*应用场景,位置参数中代表将多个参数存入元祖,**将关键字参数传入字典 位置参数: 位置形参:必须被传值,一一对应 位置实参:按从左到右的顺序与形参一一对应 关键字参数:按照key=value形式指名道姓的为形参传值,可以完全不按照顺序 1.关键字实参必须在位置参数的后面 2.可以混用位置实参与关键字实参,但不能为同一个形参重复传值 默认参数: 形参有默认值 可变长参数 形参:*args,**kwargs将多余的参数分别封装成元祖与字典 实参:将args kwargs分别打散 什么是命名关键字参

十、闭包函数、函数对象、装饰器

函数对象: 函数是第一类对象 第一类对象: 指可以在执行期创造并作为参数传递给其他函数或存入一个变量的实体 第一类对象所特有的特性为: 可以当容器被存入变量或其他结构 可以被作为参数传递给其他函数 可以被作为函数的返回值 可以在执行期创造,而无需完全在设计期全部写出 即使没有被系结至某一名称,也可以存在 函数.类.模块等所有对象都是第一类的 闭包函数: 函数内定义的函数为内部函数 内部函数包含对外部作用域而非全局作用域的引用 定义闭包函数的基本形式: def 外部函数名(): 内部函数需要的变量

闭包函数 装饰器 有参装饰器

闭包函数: 1 内部函数 2 包含对外部作用域而非全局作用域的引用闭包函数的特点: 自带作用域  延迟计算 #闭包函数定义 1 def timmer(func): 2 def inner(*args,**kwargs): 3 re = func(*args,**kwargs) 4 return re 5 return inner 6 7 index(): 8 print("hello") 9 10 index = timmer(index) #index == inner 11 ind