TL;DR:如果函数装饰器没有具体指定参数,装饰函数是否具有与未装饰的相同函数的参数要求(根据参数计数和 kwarg 名称)?
我有一个用于处理所有购物车 ajax 调用的网络应用程序的控制器。在每次调用开始时,它都会初始化一个对象,该对象处理购物车功能的实际逻辑。(这可能不是最有效的方法,但我的问题与实际的购物车位无关。)
代码如下所示:
from webapp import request
from shopping_cart import Cart
from decorators import decorator
@decorator
def init_cart(f, *args, **kwargs):
shopping_cart = Cart()
return f(shopping_cart = cart)
@init_cart
def add_item(shopping_cart = None):
shopping_cart.add(request.params)
@init_cart
def remove_item(shopping_cart = None):
shopping_cart.remove(request.params)
等等。
该代码存在于一个集中模块中,由多个应用程序导入和调用。各个应用程序中的代码如下所示:
from sharedlib.controllers import cart
from app.base import *
class CartController(BaseController):
def index(self, url = None):
set_content_type('text/javascript')
controller_method = getattr(cart, url)
if controller_method:
return controller_method()
else:
abort(404)
我的问题如下:
如果我希望 init_cart 装饰器将它接收到的参数传递给被调用的控制器方法,除了传递购物车模块之外,我还会尝试:
@decorator
def init_cart(f, *args, **kwargs):
shopping_cart = Cart()
kwargs['shopping_cart'] = cart
return f(*args, **kwargs)
@init_cart
def add_item(shopping_cart = None):
shopping_cart.add(request.params)
但我抛出异常,TypeError: add_item() got multiple values for keyword argument 'shopping_cart'
我不完全理解这种行为:kwargs 当然只有一个“shopping_cart”的键/值对。
此外,如果我尝试这个:
@decorator
def init_cart(f, *args, **kwargs):
shopping_cart = Cart()
return f(cart)
@init_cart
def add_item(shopping_cart = None):
shopping_cart.add(request.params)
我得到错误TypeError: add_item() takes exactly 1 argument (0 given)
我假设我不了解装饰器在接收和传递参数时的行为方式——我假设如果init_cart
使用(*args, **kwargs)
它所装饰的函数,则可以使用任何参数集或缺少参数集来调用它。情况似乎并非如此。
此外,在前面的示例中,该方法如何可能接收shopping_cart
参数的多个值?