我有一个由装饰器转移变量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
这是curry函数的一个很好的用例。
curry函数本质上是延迟函数的调用,直到提供了所有输入。
这可以用于各种事情,如包装器或函数式编程。在本例中,让我们创建一个接受输入的包装器。
我将使用一个简单的包pamda,其中包含一个用于python的curry函数。这可以用作其他函数的包装器。
安装 Pamda:
pip install pamda
创建一个简单的带有两个输入的装饰函数:
@pamda.curry()
def my_decorator(input, func):
print ("Executing Decorator")
print(f"input:{input}")
return func
使用提供给目标函数的第一个输入应用你的装饰器:
@my_decorator('Hi!')
def foo(input):
print('Executing Foo!')
print(f"input:{input}")
执行你的包装函数:
x=foo('Bye!')
把所有东西放在一起:
from pamda import pamda
@pamda.curry()
def my_decorator(input, func):
print ("Executing Decorator")
print(f"input:{input}")
return func
@my_decorator('Hi!')
def foo(input):
print('Executing Foo!')
print(f"input:{input}")
x=foo('Bye!')
将:
Executing Decorator
input:Hi!
Executing Foo!
input:Bye!
这是curry函数的一个很好的用例。
curry函数本质上是延迟函数的调用,直到提供了所有输入。
这可以用于各种事情,如包装器或函数式编程。在本例中,让我们创建一个接受输入的包装器。
我将使用一个简单的包pamda,其中包含一个用于python的curry函数。这可以用作其他函数的包装器。
安装 Pamda:
pip install pamda
创建一个简单的带有两个输入的装饰函数:
@pamda.curry()
def my_decorator(input, func):
print ("Executing Decorator")
print(f"input:{input}")
return func
使用提供给目标函数的第一个输入应用你的装饰器:
@my_decorator('Hi!')
def foo(input):
print('Executing Foo!')
print(f"input:{input}")
执行你的包装函数:
x=foo('Bye!')
把所有东西放在一起:
from pamda import pamda
@pamda.curry()
def my_decorator(input, func):
print ("Executing Decorator")
print(f"input:{input}")
return func
@my_decorator('Hi!')
def foo(input):
print('Executing Foo!')
print(f"input:{input}")
x=foo('Bye!')
将:
Executing Decorator
input:Hi!
Executing Foo!
input:Bye!
带参数的装饰器的语法有点不同——带参数的装饰器应该返回一个函数,该函数将接受一个函数并返回另一个函数。它应该返回一个普通的装饰器。有点困惑,对吧?我的意思是:
def decorator_factory(argument):
def decorator(function):
def wrapper(*args, **kwargs):
funny_stuff()
something_with_argument(argument)
result = function(*args, **kwargs)
more_funny_stuff()
return result
return wrapper
return decorator
在这里你可以读到更多关于这个主题的内容——也可以使用可调用对象来实现这个功能,这里也有解释。
我猜你的问题是把参数传递给你的装饰师。这有点棘手,不简单。
下面是一个如何做到这一点的例子:
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的文章。
如果函数和装饰器都必须接受参数,可以采用下面的方法。
例如,有一个名为decorator1的装饰器,它接受一个参数
@decorator1(5)
def func1(arg1, arg2):
print (arg1, arg2)
func1(1, 2)
现在,如果decorator1参数必须是动态的,或者在调用函数时传递,
def func1(arg1, arg2):
print (arg1, arg2)
a = 1
b = 2
seconds = 10
decorator1(seconds)(func1)(a, b)
在上面的代码中
Seconds是decorator1的参数
A b是func1的参数
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