python 装饰器(个人复习总结)

一. 闭包

Python中的namespace

Python中通过提供 namespace 来实现重名函数/方法、变量等信息的识别,其一共有三种 namespace,分别为:

  • local namespace: 作用范围为当前函数或者类方法
  • global namespace: 作用范围为当前模块
  • build-in namespace: 作用范围为所有模块
def outer():
    a = 1
    def inner():
        # a = a + 1
        print(a)
    inner()

outer()

此时 a = a + 1 会报错。inner() 可以使用变量a, 但是此情况下无法修改a

在Python中创建一个闭包可以归结为以下三点:

  • 闭包函数必须有内嵌函数
  • 内嵌函数需要引用该嵌套函数上一级namespace中的变量
  • 闭包函数必须返回内嵌函数

二. 装饰器:

# 装饰器的作用
    python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能
# 装饰器原则: 开放封闭原则  对拓展时开放的, 对修改是封闭的

一个简单的装饰器:

import time


def func():  # 被装饰的函数
    time.sleep(1)
    print("老板好,同事好大家好")


def timmer(f):  # 装饰器函数
    def inner():
        start = time.time()
        f()
        end = time.time()
        print(end - start)
    return inner

此时将函数func()作为参数传给timmer(),形成装饰效果

# 有参数和返回值时装饰器的模板

# 装饰器模板
def wrapper(f):  # f 被装饰的名字
    def inner(*args, **kwargs):
        '''在被装饰函数前要做的事'''
        ret = f(*args, **kwargs)
        '''在被装饰函数后要做的事'''
        return ret
    return inner

使用:

@wrapper  # 语法糖 装饰器函数名
def fun(a, b):
    time.sleep(1)
    print('老板好')
    return '新年快乐'

三. 装饰器的进阶

1 funtools.warps 工具

from funtools import warps # 可以查看被装饰的函数的名字
def wrapper(f):  # f 被装饰的名字
    # 可以正常返回函数名,而不是inner函数名。
    @warps(func) 
    def inner(*args, **kwargs):
        """在被装饰函数前要做的事"""
        ret = f(*args, **kwargs)
        """在被装饰函数后要做的事"""
        return ret
    return inner

2,带参数的装饰器。可以控制多个装饰器使用

flag = True  设置标志位 
# 再原有基础上使用一个函数嵌套装饰器
def timmer(flag):
    def warpper(func):
        # 当flag = True 时,装饰器生效。反之则不生效
        def inner(*args, **kwargs):
           if flag: 
                ret = func(*args, **kwargs)
                return ret
            else:
                pass
        return inner
    return warpper

3.多个装饰器修饰同一个函数。执行顺序。

def wrapper1(f):  # f 被装饰的名字
    def inner(*args, **kwargs):
        print('装饰器1调用前')
        ret = f(*args, **kwargs)
        print('装饰器1调用后')
        return ret

    return inner


def wrapper2(f):  # f 被装饰的名字
    def inner(*args, **kwargs):
        print('装饰器2调用前')
        ret = f(*args, **kwargs)
        print('装饰器2调用后')
        return ret

    return inner


@wrapper1
@wrapper2
def func():
    print('被装饰的函数')

func()

# 执行结果
'''
装饰器1调用前
装饰器2调用前
被装饰的函数
装饰器2调用后
装饰器1调用后
'''

  4.基于装饰器的 单例模式 

只是被修饰的对像从函数变为了类 。使用仍然相同

def singleton(cls):
    instance = {}
    def wrapper(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]
    return wrapper
@singleton
class A:
    pass

a1 = A()
a2 = A()
print(id(a1), id(a2))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值