我想知道我是否可以使用装饰器来查看函数的输入是否为:
示例:
@get_values(['username', 'password'])
def log_me_in(username, password)
# login logic
if username == password:
return True
return False
称呼它的方式:
log_me_in(username = 10, password = 10)
>>>> True
log_me_in(10, 10)
>>>> True
log_me_in({'username': 10, 'password': 10})
>>>> True
log_me_in({'username': 10, 'password': 10, 'something': 10})
>>>> True
log_me_in({'username': 10, 'something': 10})
>>>> EXCEPTION
log_me_in({})
>>>> EXCEPTION
log_me_in([])
>>>> EXCEPTION
答案 0 :(得分:1)
如果要将值作为位置参数传递(根据传递给装饰器的参数列表中的位置):
def getvalues(params):
getter = itemgetter(*params)
def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
if len(args) == 1 and not kwargs and isinstance(args[0], Mapping):
return func(*getter(args[0]))
else:
return func(*args, **kwargs)
return wrapper
return deco
如果您想将它们作为关键字参数传递:
def getvalues(params):
def deco(func):
@wraps(func)
def wrapper(*args, **kwargs):
if len(args) == 1 and not kwargs and isinstance(args[0], Mapping):
return func(**{key: value for key, value in args[0].items()
if key in params})
else:
return func(*args, **kwargs)
return wrapper
return deco
我必须制定自己的规则来填补规范中的所有空白,但我认为它们有点合理。
另外,正如我在评论中提到的,如果getvalues
将其参数名称作为单独的参数而不是列表,我认为会更友好。要解决此问题,只需将第一行更改为def getvalues(*params):
。
答案 1 :(得分:0)
有可能,是的。但这有必要吗?您可以通过使用**
传递关键字参数来获得类似的结果:
>>> log_me_in(**{'username': 10, 'password': 10})
True
唯一的区别是不允许传递something
。 Python在无法识别的关键字参数上出错。参见:
>>> log_me_in(username=10, password=10)
True
>>> log_me_in(10, 10)
True
>>> log_me_in(**{'username': 10, 'password': 10})
True
>>> log_me_in(**{'username': 10, 'password': 10, 'something': 10})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: log_me_in() got an unexpected keyword argument 'something'
>>> log_me_in(**{'username': 10, 'something': 10})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: log_me_in() got an unexpected keyword argument 'something'
>>> log_me_in(**{})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: log_me_in() missing 2 required positional arguments: 'username' and 'password'
>>> log_me_in(*[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: log_me_in() missing 2 required positional arguments: 'username' and 'password'