我正在编写一个调度方法。它接收一个从JSON解析的字典,并使用JSON字段作为函数调用中的参数。这背后的想法是我希望能够向发件人提供错误消息,但我不想写出代码来检查每个方法的参数(有几十个)。所以我使用这种方法同时提供了良好的错误信息,同时减少了我必须做的工作量。
但是,我现在正试图用装饰器包装被调用的函数。装饰者干扰了方法的检查,我无法解决这个问题。
这是现有代码的简化版本。它很棒!我收到了有用的错误消息,详细说明了哪些参数没有提供。
import inspect
class MyClass:
# There is plenty of other code in here.
...
# Here's the relevant part:
def dispatch(self, json, action):
try:
func = self.DISPATCH[action]
try:
return func(self, **json)
except TypeError:
sig = inspect.signature(func)
missing_fields = []
for param in filter(lambda p: p.name != 'self' and p.kind == p.POSITIONAL_OR_KEYWORD and p.default == p.empty, sig.parameters.values()):
if param.name not in json:
missing_fields.append(param.name)
if missing_fields:
# Tell the sender which fields they were missing.
...
else:
# Check if the number of arguments was wrong.
# Send back a good error message if that's the problem,
# otherwise `raise`.
...
except KeyError:
# The `action` was not in the `DISPATCH`.
...
def method(self, foo, bar):
# Do some stuff.
...
DISPATCH = {
'method': method,
}
现在我尝试添加此装饰器以检查用户是否在允许函数调用发生之前登录:
def _check_login(func):
def wrapper(self, *args, **kwargs):
if not self.user_is_logged_in:
# Raise the appropriate error.
...
return func(*args, **kwargs)
return wrapper
我只是将@_check_login
放在较大代码部分def method
之前的行上。但是,inspect.signature
调用现在会查看wrapper(self, *args, **kwargs)
而不是实际函数,并不断说明提供了错误的值。我明白这就是装饰者的工作方式;我正在寻找一种解决方法。