Mission1: 创建一个装饰器 可同时处理有或无字符串参数的情况
For example: 一个名为@log的decorator,使它:
#即支持
@log
def f():
pass
#又支持
@log('hello world')
def f1():
pass
Lets do it!
import functools
def log(temp):
if not isinstance(temp,str):
#使用decorator后,func指向log(func)
#将更名后的'__name__'更改回原函数名称防止签名错误
@functools.wraps(temp)
def wrapper(*args,**kw):
##operations
return temp(*args,**kw)
return wrapper
else: #此时temp为一串str参数
#new decorator
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print(temp) #打印字符串temp
#operations
return func(*args,**kw)
return wrapper
return decorator
这样的一个decorator就可以根据情况判断并正常运行了。
Mission2: 创建一个decorator并使其在函数运行前后各自打印 ‘begin call’ & ‘end call’
注意以下代码:
1st try
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print ('begin call')
return func(*args,**kw)
print('end call')##放于return值后面则不会执行
return wrapper
以上代码相信大家都能看出问题,即print(‘end call’)位于函数返回值的后面,则根本不可能执行,错误❌
2nd try
此时可能会有同学将end call放于wrapper()之后,log()的返回值之前,我们来看一下是否正确:
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print ('begin call')
return func(*args,**kw)
print('end call')##此处改动
return wrapper
@log
def plus(x,y):
print(x + y)
plus(2,5)
运行结果:
这是因为当python解释器运行log()的时候没有发现调用wrapper(),则只会单纯略过当执行到log()的返回值即wrapper()时才会运行,所以先执行的将会是print(‘end call’)
3rd try
# -*- coding: utf-8 -*-
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print ('begin call')
s = func(*args,**kw)
print('end call')
return s
return wrapper
@log
def plus(x,y):
print(x + y)
plus(2,5)
先行调用函数并赋值给一个变量,此时前后配上begin call & end call 并在最后return返回值,这样就能圆满解决问题啦~
我是萌新 请多多指教!~