Python装饰器的具体实用示例 |
您所在的位置:网站首页 › pythontime函数重新计时 › Python装饰器的具体实用示例 |
示例1:普通装饰器
def name(n):
def func(x):
res = n(x+x)
return res
return func
@name
def run(x): # run = name(run)
print(x)
if __name__ == '__main__':
run(1)
# 2
def name(n):
def func(*x):
res = n(x+x)
return res
return func
@name
def run(x): # run = name(run)
print(x)
if __name__ == '__main__':
run(1)
# (1, 1)
上述二者的比较,注意传参参数。一个是普通的传值,一个是两个元组相加。 示例2:普通装饰器传值 def name(n): def func(x, y): res = n(x,y) return res return func @name def run(x, y): # run = name(run) print(x, y) if __name__ == '__main__': run(1, 2) # 1 2试想,如何才能实现1+2,run函数中还是name函数中 def name(n): def func(x, y): res = n(x,y) return res return func @name def run(x, y): # run = name(run) print(x + y) if __name__ == '__main__': run(1, 2)在run函数中实现,name函数作用近似于调用的操作,也可以在name函数中实现 def name(n): def func(x, y): res = n(x,y) print(x + y) return res return func @name def run(x, y): # run = name(run) # print(x + y) pass if __name__ == '__main__': run(1, 2) 示例3-进阶:日志 import logging def name(n): def func(x, y): res = n(x,y) logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ' '%(lineno)d %(message)s', level=logging.DEBUG) logging.info("执行了{},{},结果是{}".format(x,y,res)) return res return func @name def run(x, y): # run = name(run) return x+y if __name__ == '__main__': run(1, 2) # 2023-03-01 12:24:10,474 root 20 ceshi_test.py 10 执行了1,2,结果是3这里的结果貌似没有指明函数,影响不大,可以看看logging模块,也可以自己加。 import logging def name(n): def func(x, y): res = n(x,y) logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ' '%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG) logging.info("执行了{},{},{},结果是{}".format(n.__name__,x,y,res)) return res return func @name def run(x, y): # run = name(run) return x+y if __name__ == '__main__': run(1, 2) # 2023-03-01 12:35:15,283 root 20 ceshi_test.py 9 func 执行了run,1,2,结果是3可以看到,获取的运行函数其实不太一样。要想准确的获取,建议手写 示例4-进阶:时间计时器 import time def timer(clock): def func(*args,**kwargs): start = time.time() res = clock(*args,**kwargs) print("耗时 {} S".format(time.time() - start)) return res return func @timer def run(x, y): time.sleep(1) print(x + y) if __name__ == '__main__': run(1, 2) # 3 # 耗时 1.0103626251220703 S上述是在不做任何操作的情况下,单纯用来计算程序运行时间。 示例5-再进阶-带参 def outwapper(out): def country(cont): def inwapper(*args,**kwargs): if out == '中国': print("你好啊,兄弟") else: print("你是哪个国家的") cont(*args,**kwargs) return inwapper return country @outwapper("中国") def people(): pass if __name__ == '__main__': people()是不是看起来麻烦了很多,仔细一看其实也久那么回事。传个参数,该返回的值还是得返回。 def outwapper(out): def country(cont): def inwapper(*args,**kwargs): if out == '中国': print("你好啊,兄弟") else: print("你是哪个国家的") cont(*args,**kwargs) return inwapper return country @outwapper("中国") @outwapper("俄罗斯") def people(): pass if __name__ == '__main__': people() # 你好啊,兄弟 # 你是哪个国家的可以多个装饰器作用同一个函数上,也能重复使用。 示例6-高阶-类装饰器 class Time(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print(args,kwargs) @Time def name(): pass if __name__ == '__main__': name()套用格式即可,__init__中的参数是必须的,因为需要传递函数。 class Time(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print(args,kwargs) @Time def name(x,y): pass if __name__ == '__main__': name('清安',age=18) # ('清安',) {'age': 18}很明显了吧,__call__中用来接收值并处理的。 传参 class Time(object): def __init__(self, func): self.func = func def __call__(self, evt): def wapper(*args, **kwargs): print(self.func, args, kwargs) return wapper @Time("中国") def name(x, y): pass if __name__ == '__main__': name('清安', age=18) # 中国 ('清安',) {'age': 18}evt是啥? class Time(object): def __init__(self, func): self.func = func def __call__(self, evt): def wapper(*args, **kwargs): print(evt.__name__, args, kwargs) return wapper @Time("中国") def name(x, y): print(x,y) if __name__ == '__main__': name('清安', age=18) # name ('清安',) {'age': 18}就是name函数的函数地址,如何使用evt参数呢? class Time(object): def __init__(self, func): self.func = func def __call__(self, evt): def wapper(*args, **kwargs): evt(args,kwargs) # print(evt.__name__, args, kwargs) return wapper @Time("中国") def name(x, y): print(x,y) if __name__ == '__main__': name('清安', age=18)就是这么简单。 示例7-高阶-装饰类的装饰器 def func(cls): def inwapper(*args,**kwargs): print(cls.__name__) print(args) return inwapper @func class User: def __init__(self,name): self.name = name if __name__ == '__main__': User("清an") # User # ('清an',) 类中函数使用装饰器 def func(cls): def inwapper(x, *args, **kwargs): logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ' '%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG) logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs)) return inwapper # @func class User: @func def name(self, name, name1, age): # return name, name1, age pass if __name__ == '__main__': u = User() u.name("清安","ANAN",age=18) 2023-03-01 18:36:36,310 root 20 ceshi_test.py 74 inwapper 执行了name,结果是,('清安', 'ANAN'),{'age': 18}为什么要有个x,因为self会被当作参数传递,直接把内存地址一起传走了,要么下标取值要么再来个参数接收这个self。要么类中不使用self ❝既然使用了self,那么装饰器中能用来调用属性吗,答案是当然可以。 ❞ def func(cls): def inwapper(x, *args, **kwargs): logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ' '%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG) x.info = 1 logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs)) return inwapper class User: info = None @func def name(self, name, name1, age): # return name, name1, age pass if __name__ == '__main__': u = User() u.name("清安","ANAN",age=18) print(u.info) # 1 # 2023-03-02 09:15:36,640 root 20 ceshi_test.py 75 inwapper 执行了name,结果是,('清安', 'ANAN'),{'age': 18} ❝显而易见,赋值成功。再来看看对其他函数赋值。 ❞ def func(cls): def inwapper(x, *args, **kwargs): logging.basicConfig(format='%(asctime)s %(name)s %(levelno)s %(filename)s ' '%(lineno)d %(funcName)s %(message)s', level=logging.DEBUG) x.Info("QA",18) logging.info("执行了{},结果是{},{},{}".format(cls.__name__,x, args, kwargs)) return inwapper class User: info = None @func def name(self, name, name1, age): # return name, name1, age pass def Info(self,name,age): print("我是{},今年{}".format(name,age)) if __name__ == '__main__': u = User() u.name("清安","ANAN",age=18) # 2023-03-02 09:19:26,910 root 20 ceshi_test.py 75 inwapper 执行了name,结果是,('清安', 'ANAN'),{'age': 18} # 我是QA,今年18 示例8-伪装 from functools import wraps def timer(value): def func(fun): # @wraps(fun) def inner(*args,**kwargs): res = fun() print(value) print(inner.__name__) return res return inner return func @timer("QA") def run(): pass if __name__ == '__main__': run() ❝伪装装饰器,让装饰器函数名称指向运行函数名。 ❞此外还有一些用法,此处就不再阐述,学习完上述的示例后,你是否能自己写出一个像样的装饰器呢? |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |