Python - Самый чистый способ переопределить __init__, где после вызова super() следует использовать необязательный kwarg?

Мне нравится, как красиво выглядит python/чувствует, и я надеюсь, что это может быть чище (читаемость потрясающая).

Какой чистый способ принять необязательный аргумент ключевого слова при переопределении подкласса init, где необходимо использовать kwarg после вызова super()?

У меня есть форма django, где я хочу принять необязательный аргумент пользователя, но если я определяю его как один из аргументов user=None, тогда обычный вызов формы form({}) предполагает, что позиционный аргумент ссылается на ключевое слово аргумент user.

Код говорит лучше, чем (мои) слова:

def __init__(self, *args, **kwargs):
    user = None
    if 'user' in kwargs:
        user = kwargs.pop('user')
    super(BaseCheckoutForm, self).__init__(*args, **kwargs)
    if user:
        self.prefill_from_user(user)

Я могу сделать это самым чистым, посмотрев фактический класс Form, чтобы увидеть, какие аргументы он ищет, но одна из самых больших вещей о подклассификации чего-либо в python - это собрать все args и kwargs и передать его в то, что вы подклассифицировали. Также это не зависит от каких-либо изменений в источнике.

def __init__(self, querydict=None, user=None):
    super(BaseCheckoutForm, self).__init__(querydict)
    if user:
        self.prefill_from_user(user)

Но, к сожалению, у меня есть:

 def __init__(self, *args, **kwargs):
    # cannot define user=None as an argument because normal usage
    # of class expects a certain order of positional args
    user = None
    if 'user' in kwargs:
        # must pop now since super()__init__ isn't expecting a user kwarg
        user = kwargs.pop('user') 
    super(BaseCheckoutForm, self).__init__(*args, **kwargs)
    if user:
        self.prefill_from_user(user)

Спасибо за любой вклад!

Ответ 1

Обычно я просто делаю то, что вы здесь делаете. Однако вы можете сократить/очистить свой код, предоставив аргумент по умолчанию dict.pop:

 def __init__(self, *args, **kwargs):
    user = kwargs.pop('user', None)
    super(BaseCheckoutForm, self).__init__(*args, **kwargs)
    if user is not None:
        self.prefill_from_user(user)