栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【Python】Python装饰器

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Python】Python装饰器

文章目录
  • 1. 装饰器的定义与原型
  • 2. 装饰器应用场景 - 统计函数执行时间
  • 3. 装饰器语法
    • 3.1. 装饰器嵌套
    • 3.2. 装饰带有参数的函数
    • 3.3. 带有参数的装饰器
    • 3.4. 类装饰器装饰函数
    • 3.5. 用类方法装饰函数
    • 3.6. 函数装饰器装饰类
    • 3.7. 类装饰器装饰类

1. 装饰器的定义与原型
  • 装饰器定义
    在不改变原有函数代码,且保持原函数调用方法不变的情况下,给原函数增加新的功能(或者给类添加属性和方法)
    • 核心思想
      用一个函数(或者类)去装饰一个旧函数(或者类),造成一个新函数(或新类)
    • 语法规则
      在原有的函数上加上@,装饰器会把下面的函数当作参数转递到装饰器中,@又被称为语法糖
    • 应用场景
      引入日志,函数执行时间的统计,执行函数前的准备工作,执行函数后的处理工作,权限校验,缓存等
  • 装饰器的原型
    利用闭包,把函数当作参数传递,并在函数内去调用传递进来的函数,并返回一个函数
    • 闭包
    def outer(func):
    	def inner():
    		# 功能1
    		func()
    		# 功能2
    	return inner
    
    def old():
    	# 旧函数功能
    old = outer(old) # 返回inner函数赋给old
    old() # 相当于inner()
    # 执行结果
    1. 功能1
    2. 旧函数功能
    3. 功能2
    
    • 装饰器
    def outer(func):
    	def inner():
    		# 功能1
    		func()
    		# 功能2
    	return inner
    @outer # 此处相当于old = outer(old)
    def old():
    	# 旧函数功能
    
2. 装饰器应用场景 - 统计函数执行时间
import time

def runtime(func):
    def inner():
        start = time.perf_counter()
        func()
        end = time.perf_counter()
        print(f'函数的执行时间为:{end - start:0.2f}')
    return inner

@runtime
def func():
    for i in range(10):
        print(i)
        time.sleep(1)
        
func()        
3. 装饰器语法 3.1. 装饰器嵌套
  • 先使用离得近的装饰器,在装饰完的基础上,继续新的装饰
import time

def runtime(func):
    def inner():
        start = time.perf_counter()
        func()
        end = time.perf_counter()
        print(f'函数的执行时间为:{end - start:0.2f}')
    return inner

def log(func):
    def inner():
        print(time.gmtime(time.time()).tm_sec)
        func()
        print(time.gmtime(time.time()).tm_sec)
    return inner

@log
@runtime	# 相当于func = log(func = runtime(func))
def func():
    for i in range(10):
        time.sleep(1)
        
func()  
'''
执行结果
执行前的秒数
函数的执行时间
执行后的秒数
'''
3.2. 装饰带有参数的函数
  • 内函数带有旧函数的所有参数
import time

def runtime(func):
    def inner(name):
        start = time.perf_counter()
        func(name)
        end = time.perf_counter()
        print(f'函数的执行时间为:{end - start:0.2f}')
    return inner

@runtime
def func(name):
    print(name)       
 
func('Jack')
3.3. 带有参数的装饰器
  • 可以通过此参数选择装饰方法
import time

def choose(opt):
    def runtime(func):
        def inner1(name):
            start = time.perf_counter()
            func(name)
            end = time.perf_counter()
            print(f'函数的执行时间为:{end - start:0.2f}')
        def inner2(name):
            print('Hello')
            func(name)
        if opt == 1:
            return inner1
        else:
            return inner2
    return runtime

@choose(2)
def func(name):
    print(name)       
 
func('Jack')        
3.4. 类装饰器装饰函数
  • 此时的func函数是属于类Outer的inner方法
class Outer():
    # 当把该类当作函数调用时,obj()自动触发__call__
    def __call__(self, func):
        self.func = func
        return self.inner
    def inner(self):
        print(1)
        self.func()
        print(2)
        
@Outer()        
def func():
    print('Hello')

func()
3.5. 用类方法装饰函数
class Test():
    def outer(self,func):
        self.func = func
        return self.inner
    
    def inner(self):
        print(1)
        self.func()
        print(2)
        
@Test.outer       
def func():
    print('Hello')

func()
3.6. 函数装饰器装饰类
  • 为类添加新属性、新方法
def Outer(_class):
    def newfunc():
        print('新方法')
    _class.newfunc = newfunc
    _class.newattrib = '新属性'
    return _class

@Outer
class Test():
    def outer(self,func):
        self.func = func
        return self.inner
    
    def inner(self):
        print(1)
        self.func()
        print(2)

Test.newfunc()
print(Test.newattrib)
3.7. 类装饰器装饰类
  • 接收类,装饰类,返回新类
class Outer():
    def __init__(self) -> None:
        self.name = '新属性'
    def __call__(self, _class):
        _class.newfunc = self.newfunc     
        _class.newattrib = self.name   
        return _class
    def newfunc(self):
        print('新方法')
    
@Outer()
class Test():
    def outer(self,func):
        self.func = func
        return self.inner
    
    def inner(self):
        print(1)
        self.func()
        print(2)

Test.newfunc()
print(Test.newattrib)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303879.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号