我有一个由装饰器转移变量insurance_mode的问题。我将通过以下装饰器语句来实现:
@execute_complete_reservation(True)
def test_booking_gta_object(self):
self.test_select_gta_object()
但不幸的是,这种说法并不管用。也许也许有更好的办法来解决这个问题。
def execute_complete_reservation(test_case,insurance_mode):
def inner_function(self,*args,**kwargs):
self.test_create_qsf_query()
test_case(self,*args,**kwargs)
self.test_select_room_option()
if insurance_mode:
self.test_accept_insurance_crosseling()
else:
self.test_decline_insurance_crosseling()
self.test_configure_pax_details()
self.test_configure_payer_details
return inner_function
我猜你的问题是把参数传递给你的装饰师。这有点棘手,不简单。
下面是一个如何做到这一点的例子:
class MyDec(object):
def __init__(self,flag):
self.flag = flag
def __call__(self, original_func):
decorator_self = self
def wrappee( *args, **kwargs):
print 'in decorator before wrapee with flag ',decorator_self.flag
original_func(*args,**kwargs)
print 'in decorator after wrapee with flag ',decorator_self.flag
return wrappee
@MyDec('foo de fa fa')
def bar(a,b,c):
print 'in bar',a,b,c
bar('x','y','z')
打印:
in decorator before wrapee with flag foo de fa fa
in bar x y z
in decorator after wrapee with flag foo de fa fa
详见Bruce Eckel的文章。
例如,我在下面创建了multiply(),它可以接受一个参数或不接受参数,也可以不接受装饰器的括号,我在下面创建了sum():
from numbers import Number
def multiply(num=1):
def _multiply(func):
def core(*args, **kwargs):
result = func(*args, **kwargs)
if isinstance(num, Number):
return result * num
else:
return result
return core
if callable(num):
return _multiply(num)
else:
return _multiply
def sum(num1, num2):
return num1 + num2
现在,我把@multiply(5)放在sum()上,然后调用sum(4,6),如下所示:
# (4 + 6) x 5 = 50
@multiply(5) # Here
def sum(num1, num2):
return num1 + num2
result = sum(4, 6)
print(result)
那么,我可以得到如下结果:
50
接下来,我把@multiply()放在sum()上,然后调用sum(4,6),如下所示:
# (4 + 6) x 1 = 10
@multiply() # Here
def sum(num1, num2):
return num1 + num2
result = sum(4, 6)
print(result)
或者,我把@multiply放在sum()上,然后调用sum(4,6),如下所示:
# 4 + 6 = 10
@multiply # Here
def sum(num1, num2):
return num1 + num2
result = sum(4, 6)
print(result)
那么,我可以得到如下结果:
10
def decorator(argument):
def real_decorator(function):
def wrapper(*args):
for arg in args:
assert type(arg)==int,f'{arg} is not an interger'
result = function(*args)
result = result*argument
return result
return wrapper
return real_decorator
装饰器的使用
@decorator(2)
def adder(*args):
sum=0
for i in args:
sum+=i
return sum
然后
adder(2,3)
生产
10
but
adder('hi',3)
生产
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-143-242a8feb1cc4> in <module>
----> 1 adder('hi',3)
<ipython-input-140-d3420c248ebd> in wrapper(*args)
3 def wrapper(*args):
4 for arg in args:
----> 5 assert type(arg)==int,f'{arg} is not an interger'
6 result = function(*args)
7 result = result*argument
AssertionError: hi is not an interger
上面的回答很棒。这个例子还演示了@wraps,它从原始函数中获取文档字符串和函数名,并将其应用于新的包装版本:
from functools import wraps
def decorator_func_with_args(arg1, arg2):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
print("Before orginal function with decorator args:", arg1, arg2)
result = f(*args, **kwargs)
print("Ran after the orginal function")
return result
return wrapper
return decorator
@decorator_func_with_args("foo", "bar")
def hello(name):
"""A function which prints a greeting to the name provided.
"""
print('hello ', name)
return 42
print("Starting script..")
x = hello('Bob')
print("The value of x is:", x)
print("The wrapped functions docstring is:", hello.__doc__)
print("The wrapped functions name is:", hello.__name__)
打印:
Starting script..
Before orginal function with decorator args: foo bar
hello Bob
Ran after the orginal function
The value of x is: 42
The wrapped functions docstring is: A function which prints a greeting to the name provided.
The wrapped functions name is: hello
定义这个decoratorize函数来生成定制的decorator函数:
def decoratorize(FUN, **kw):
def foo(*args, **kws):
return FUN(*args, **kws, **kw)
return foo
可以这样用:
@decoratorize(FUN, arg1 = , arg2 = , ...)
def bar(...):
...