424python装饰器

# 全局作用域(全局变量) ==》在全局作用域中访问全局变量,也可以在局部作用域中访问
import time

num1 = 10


def func():
    # 局部作用域(局部变量)==》在局部作用域中访问局部变量,但是在全局作用域中无法访问
    num2 = 20
    # ① 在局部访问局部变量
    print(num2)


# ① 在全局访问全局变量
print(num1)
# 调用函数
func()
print('----------------------------------')


# 闭包三步走
# 1 有嵌套
def outer():
    b = 20

    def inner():
        # 2.有引用,内部函数引用了外部函数的局部变量
        print(b)

    # 3.有返回,内部函数的名称==》内存地址返回
    return inner


# 调用outer函数

f = outer()
f()  # 调用inner函数,返回outer函数中的局部变量b

print('------------------------------------')

'''
闭包的变量修改
'''
b = 50


# 1 有嵌套
def outer():
    b = 20

    def inner():
        # 2.有引用,内部函数引用了外部函数的局部变量
        # global b
        # nonlocal关键字 用于嵌套环境,适用于在嵌套内部修改外部变量
        nonlocal b
        b = 30
        print(b)

    # 3.有返回,内部函数的名称==》内存地址返回
    print(f'outer中的b:{b}')
    inner()
    print(f'inner执行后outer中的{b}')


# 调用outer函数

outer()
print(b)

print('-------------------------------')


def func():
    result = 0

    def inner(num):
        nonlocal result
        result += num
        print(result)

    return inner


f = func()
f(1)
f(2)
f(3)

print('-------------------------------')


# 装饰器
def check(fn):
    def inner():
        # 开发登录功能
        print('登录功能')
        # 调用原函数
        fn()

    return inner


# 评论功能(前提:登录)
@check  # 装饰器
def comment():
    print('评论功能')


# comment = check(comment)  #调用check装饰器,然后把comment函数的内存地址赋值给check的fn参数
comment()  # 由于comment指向了inner函数,所有commen()代表执行inner函数
print('--------------------------')


# 下载功能(前提:登录)
@check
def download():
    print('下载功能')


# download = check(download)

download()

print('----------------------')


# 定义一个装饰器
def get_time(fn):
    # fn局部变量
    def inner():
        # 给fn添加额外功能
        start = time.time()
        fn()
        stop = time.time()
        print(stop - start)

    return inner


# 原函数
@get_time
def func1():
    list1 = []
    for i in range(100000):
        list1.append(i)


# 调用函数
func1()

print('----------------------------')


# 编写通用装饰器:用于给每个函数增加日志输出功能

def logging(fn):
    def inner(n1,n2):
        print('输出日志:正在计算加法运算')
        fn(n1,n2)

    return inner


# 原有函数
@logging
def sum_num(n1, n2):
    # print('输出日志:正在计算加法运算')
    print(n1 + n2)


# 调用方式
sum_num(10, 20)  # 相当于执行inner(10,20)
print('-----------------------------------')

# 通用装饰器,使用*args  **kwargs,可以接收任意长度参数
# 编写通用装饰器:用于给每个函数增加日志输出功能

def logging(fn):
    def inner(*args,**kwargs):
        print('输出日志:正在计算加法运算')
        fn(*args,**kwargs)

    return inner


# 原有函数
@logging
def sum_num(n1, n2):
    # print('输出日志:正在计算加法运算')
    print(n1 + n2)


# 调用方式
sum_num(10, 20)  # 相当于执行inner(10,20)
print('---------------------------------')

def logging2(fn):
    def inner(*args, **kwargs):
        # 添加装饰器代码(输出日志信息)
        print('-- 日志信息:正在努力计算机 --')
        # 执行要修饰的函数
        fn(*args, **kwargs)  # sum_num(a, b)
    return inner

@logging2
def sum_num(*args, **kwargs):
    result = 0
    # *args代表不定长元组参数,args = (10, 20)
    for i in args:
        result += i
    # **kwargs代表不定长字典参数, kwargs = {a:30, b:40}
    for i in kwargs.values():
        result += i
    print(result)

# sum_num带4个参数,而且类型不同,10和20以元组形式传递,a=30,b=40以字典形式传递
sum_num(10, 20, a=30, b=40)

print('------------------------------')

#装饰器修饰带有返回值的参数
def logging3(fn):

    def inner(*args,**kwargs):
        print('------输出日志----')
        # fn(*args,**kwargs)
        # return None  由于inner没有返回值 所有也要加terurn
        return fn(*args,**kwargs)
    return inner

@logging3
def func3(n1,n2):
    result = n1+n2
    return result

print(func3(1,2))

# 通用装饰器编写
def logging4(fn):
    def inner(*args,**kwargs):
        print('------输出日志----')
        return fn(*args,**kwargs)
    return inner

@logging4
def sum_number(n1,n2):
    return n1-n2
@logging4
def sub_number(n1,n2):
    return n1+n2

print(sum_number(10,20))
print(sub_number(10,20))
print('++++++++++++++++++++++++')

# 高级装饰器,实现装饰器传参数
def logging(flag):
    # flag = + 或 flag = -
    def decorator(fn):
        def inner(*args, **kwargs):
            if flag == '+':
                print('-- 日志信息:正在努力进行加法运算 --')
            elif flag == '-':
                print('-- 日志信息:正在努力进行减法运算 --')
            return fn(*args, **kwargs)
        return inner
    return decorator

@logging('+')
def sum_num(a, b):
    result = a + b
    return result

@logging('-')
def sub_num(a, b):
    result = a - b
    return result


print(sum_num(10, 20))
print(sub_num(100, 80))

# 类装饰器
class Check():
    def __init__(self, fn):
        # fn就是要修饰函数的名称,当Check装饰器类被调用时,系统会自动把comment函数名称传递给fn变量
        self.__fn = fn
    # __call__方法:把一个类转换为函数的形式进行调用
    def __call__(self, *args, **kwargs):
        # 编写装饰器代码
        print('请先登录')
        # 调用comment函数本身
        self.__fn(*args, **kwargs)

# 编写一个函数,用于实现评论功能,底层comment = Check(comment)
@Check
def comment():
    print('评论功能')

# 调用comment函数,实现评论功能
comment()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值