Python-декоратор, чтобы убедиться, что kwargs верны - PullRequest
2 голосов
/ 19 сентября 2009

Я создал декоратор, который использовал, чтобы гарантировать, что аргументы ключевых слов, передаваемые конструктору, являются правильными / ожидаемыми . Код следующий: </p> <pre><code>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

Пример использования этого декоратора будет следующим: </p> <pre><code>class Person(object): @keyargs_check(("name", "surname", "age")) def __init__(self, **kwargs): # perform init according to args

Используя приведенный выше код, если разработчик передает ключевые аргументы типа «бла», он выдаст исключение . К сожалению, моя реализация имеет серьезную проблему с наследованием, если я определю следующее: </p> <pre><code>class PersonTest(Person): @keyargs_check(("test")) def __init__(self, **kwargs): Person.__init__(self,**kwargs)

Поскольку я передаю kwargs методу init суперкласса, я получу исключение, потому что «test» не находится в кортеже , передаваемом декоратору суперкласса. Есть ли способ, чтобы декоратор, используемый в суперклассе, узнал о дополнительных ключевых словах? или событие лучше, есть ли стандартный способ добиться того, чего я хочу?

Обновление: меня больше интересует автоматизация способа выдачи исключения, когда разработчик передает неправильный kwarg, а не тот факт, что я использую kwargs вместо args. Я имею в виду, что я не хочу писать код, который проверяет аргументы, передаваемые методу в каждом классе.

1 Ответ

4 голосов
/ 19 сентября 2009

Ваш декоратор не нужен. Единственное, что не может сделать декоратор со стандартным синтаксисом, - это предотвращает поглощение позиционными аргументами аргументов ключевых слов. Таким образом

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)

Преимущество этого в том, что kwargs в Child не будет содержать test. Проблема в том, что вы можете испортить его с помощью звонка типа c = Child('red herring'). Это исправлено в python 3.0 .

Проблема с вашим подходом заключается в том, что вы пытаетесь использовать декоратор для выполнения макрокоманды, что непитонно. Единственное, что даст вам то, что вы хотите, - это то, что изменяет локальные значения самой внутренней функции (f в вашем коде, в частности, переменную kwargs). Как ваш декоратор должен знать внутренности обертки, как он узнает, что он вызывает суперкласс?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...