我已经做了一个装饰器,我用来确保传递给构造函数的关键字参数是正确/预期的。代码如下: Python装饰器,以确保kwargs正确
from functools import wraps
def keyargs_check(keywords):
"""
This decorator ensures that the keys passed in kwargs are the onces that
are specified in the passed tuple. When applied this decorate will
check the keywords and will throw an exception if the developer used
one that is not recognized.
@type keywords: tuple
@param keywords: A tuple with all the keywords recognized by the function.
"""
def wrap(f):
@wraps(f)
def newFunction(*args, **kw):
# we are going to add an extra check in kw
for current_key in kw.keys():
if not current_key in keywords:
raise ValueError(
"The key {0} is a not recognized parameters by {1}.".format(
current_key, f.__name__))
return f(*args, **kw)
return newFunction
return wrap
一个例子使用这个装饰的将是如下:
class Person(object):
@keyargs_check(("name", "surname", "age"))
def __init__(self, **kwargs):
# perform init according to args
使用上面的代码,如果开发商逝者如斯“嗒嗒”的关键ARGS就会抛出一个异常。不幸的是我的实现与继承的一大难题,如果我定义如下:
class PersonTest(Person):
@keyargs_check(("test"))
def __init__(self, **kwargs):
Person.__init__(self,**kwargs)
因为我传递kwargs给超类的init方法,我会得到一个例外,因为“测试” 不在传递给超类的装饰器的元组中。有没有办法让超类中使用的装饰器知道额外的关键字?或事件更好,是否有一个标准的方式来实现我想要的?
更新:我更感兴趣的是当我开发人员通过错误的kwarg而不是使用kwargs而不是args时,我抛出异常的方式自动化。我的意思是,我不想编写代码来检查每个班级传递给该方法的参数。
我理解你的观点,并且我确实考虑过使用* args,但是这给了我一个问题,我不想做以下事情: example = Base(u“”,u“” 26) 并喜欢使用: 例如=基地(年龄= 29) 使用kwargs的理由是,我有很多的争论,我不希望开发者必须通过所有默认值! – mandel 2009-09-18 20:33:07
David编写代码的方式,您不必提供默认参数。你可以构建一个基地(年龄= 29)的基地。 – 2009-09-18 21:17:21
确实,但我想在每个类和我中执行检查,但是使用装饰器会增加代码重用。我不想在每个对象中添加检查。我更喜欢使用装饰器,但即使我使用了一个函数,我也会遇到同样的问题。 – mandel 2009-09-18 22:08:26