Python decoder to ensure kwargs validity

I made a decorator that I used to ensure that the keyword arguments passed to the constructor are correct / expected . The code is as follows:

 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 

code> An example of using this decorator will be as follows:

 class Person(object): @keyargs_check(("name", "surname", "age")) def __init__(self, **kwargs): # perform init according to args 

code> Using the code above, if a developer passes key arguments like "blah", it will throw an exception . Unfortunately, my implementation has a serious inheritance problem if I define the following:

 class PersonTest(Person): @keyargs_check(("test")) def __init__(self, **kwargs): Person.__init__(self,**kwargs) 

code>

Since I am passing kwargs to the init method of the super class, I am going to get an exception because "test" is not in the tuple passed to the superclass decorator. Is there a way to let the decorator used in the superclass learn about additional keywords? or the event is better, is there a standard way to achieve what I want?

Update: I'm more interested in automating how I throw an exception when a developer passes the wrong kwarg, rather than the fact that I use kwargs instead of args. I mean, I don’t want to write code that checks the arguments passed to the method in each class.

+2
python
Sep 18 '09 at 20:01
source share
1 answer

Your decorator is not needed. The only thing a decorator does that cannot be done with standard syntax is to prevent the absorption of positional arguments by keywords. In this way,

 class Base(object): def __init__(name=None,surname=None,age=None): #some code class Child(Base): def __init__(test=None,**kwargs): Base.__init__(self,**kwargs) 

The advantage of this is that kwargs in Child will not contain test . The problem is that you can disable it with a call like c = Child('red herring') . This is fixed in python 3.0 .

The problem with your approach is that you are trying to use a decorator to perform macro tracking, which is non-pythonic. The only thing you need is what changes the locales of the innermost function ( f in your code, in particular, the kwargs variable). How does your decorator recognize wrappers inside, how does he know that he is calling a superclass?

+4
Sep 18 '09 at 20:26
source share



All Articles