python基础--修饰器

修饰器(语法糖)

在python中函数实际上就是一个对象

def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
def double(x):
    return x * 2
def triple(x):
   	return x * 3

def calc_number(func, x):
    print(func(x))

calc_number(double, 3)
calc_number(triple, 3)

函数自己也可以作为返回值

修饰器

新的代码需要在一个函数的前面或者后面添加一段代码

def dec(f):
    pass

@dec
def double(x):
    return x * 2

#等价于
double = dec(double)

会把下面的函数传给这一个装饰器函数, 装饰器需要返回新的函数, 这一个返回值会成为新的下面的函数

import time 

def timeit(f):
    def wrapper(x):
        start = time.time()
        ret = f(x)
        print(time.time() - start)
        return ret
    
    return wrapper

@timeit
def myfunction(x):
    time.sleep(x)

# myfunction(1)

@timeit
def other_func(x):
    return x*2

print(other_func(2))

带参数

import time
def timeit(f):
    def wrapper(*args, **kwargs):			#传入的参数不限制
        start = time.time()
        ret = f(*args, **kwargs)			# 会把传入的函数在这里执行
        print(time.time() - start)
        return ret
    return wrapper

@timeit
def myfunc(x):
    time.sleep(x)

@timeit
def add(x, y):
    return x+y

print(add(2, 3))

接下来就讲装饰器,其实装饰器就是一个闭包,装饰器是闭包的一种应用。什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

import time

def timeit(repeats):
    def decorator(func):
        def wrapper(*args, **kwargs):
            total_time = 0
            for _ in range(repeats):		# 1000决定这一个函数的执行次数
                start_time = time.time()
                result = func(*args, **kwargs)	# 获取一个result
                end_time = time.time()
                total_time += end_time - start_time
            average_time = total_time / repeats
            print(f"Average execution time: {average_time} seconds")
            return result
        return wrapper
    return decorator

@timeit(1000)
def double(x):
    return x * 2

# Equivalent to:
# double = timeit(1000)(double)

# Test the function
print(double(2))

前面的返回的是一个函数(这一个函数会被作为修饰器), 返回的这一个修饰器调用double再返回一个实际可以执行的函数

修饰器闭包

import time
def timeit(interation):
    def inner(f):
        def wrapper(*args, **kwargs):
            start = time.time()
            for _ in range(interation):
                print("1")
                ret = f(*args, **kwargs)
            ret = f(*args, **kwargs)
            print(time.time() - start)
            return ret
    
        return wrapper
    return inner


@timeit(10)
def double(x):
    return x*2

print(double(2))

等价于

inner = timeit(10)  # 返回一个修饰器
double = inner(double)	# 使用这一个修饰器进行修饰
import time

def inner(f):
  def wrapper(*args, **kwargs):
      start = time.time()
       for _ in range(10):
           print("1")
           ret = f(*args, **kwargs)
       ret = f(*args, **kwargs)
       print(time.time() - start)
       return ret

   return wrapper
   return inner

@inner
def double(x):
 return x*2

装饰器实际装饰的时间是在python解析到这一个函数的时候, 实际执行函数的时候不用再次装饰

实际这一个装饰就是一个闭包, 不同的是这一个闭包对它的参数的使用, 修饰器把这一个参数作为可调用的对象使用

多次修饰

def makeBlod(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

def makeItalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped


@makeBlod
@makeItalic
def hello():
    return "hello world"

print(hello())
PS E:\JHY\python\2024-4-22> python -u "e:\JHY\python\2024-4-22\main.py"
<b><i>hello world</i></b>

装饰的时候会先调用离得近的那一个

类为装饰器

import time
class Test(object):
    def __init__(self, func):
        print("初始化")
        print("func name is %s" % func.__name__)
        self.__func = func

    def __call__(self):
        print("装饰器中的功能")
        self.__func()


@Test
def test():
    print("test函数")

test()

这一个实际调用的时候是test = Test(test), 创建了一个对象

import time
class Test(object):
    def __init__(self, num):
        print("初始化")
        self.__num = num

    def __call__(self, func):
        print("装饰器中的功能")
        def inner():
            print("inner函数, num = %d" % self.__num)
            func()
        return inner
    
@Test(10)
def test():
    print("test函数")

test()

这里是先获取一个对象, 这一个对象的执行是一个修饰器

class Test(object):
    def __init__(self, num):
        print("初始化")
        self.__num = num

    def __call__(self, func):
        print("装饰器中的功能")
        self.__func = func
        return self.call_old_func
    
    def call_old_func(self):
        print("inner函数")
        self.__func()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值