Python—重写_init _uuu的最干净方法,其中在super()调用之后必须使用可选的kwarg?

Python—重写_init _uuu的最干净方法,其中在super()调用之后必须使用可选的kwarg?,python,django,Python,Django,我喜欢python的外观/感觉,我希望它更简洁(可读性非常好) 当重写子类init时,如果在super()调用之后必须使用可选的kwarg,那么接受可选关键字参数的干净方法是什么 我有一个django表单,在这里我想接受一个可选的用户参数,但是如果我将它定义为一个参数user=None,那么通常的表单调用form({})假设位置参数引用关键字参数user 代码比(我的)语言更能说明问题: 我可以通过查看实际的表单类来查看它要查找的参数,从而使这一点变得最清晰,但是在python中对任何对象进行子

我喜欢python的外观/感觉,我希望它更简洁(可读性非常好)

当重写子类init时,如果在
super()调用之后必须使用可选的
kwarg
,那么接受可选关键字参数的干净方法是什么

我有一个django表单,在这里我想接受一个可选的用户参数,但是如果我将它定义为一个参数
user=None
,那么通常的表单调用
form({})
假设位置参数引用关键字参数
user

代码比(我的)语言更能说明问题:

我可以通过查看实际的
表单
类来查看它要查找的参数,从而使这一点变得最清晰,但是在python中对任何对象进行子类化的最大好处之一是收集所有
参数
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)

谢谢你的意见

我通常只做你在这里做的事情。但是,您可以通过向
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)

哦,非常好!我不知道爸爸还有第二次争吵。你能告诉我我没有那么频繁地
pop
吗?那有帮助@Yuji-这当然是一个很好的功能!不要忘记,您可以为
dict.get
使用默认值,也可以避免
KeyError
s。也就是说,当
'a'
不在
x
@Joe中时,如果你想避免出现键错误,请使用
x.get('a',defaultvalue)
而不是
x['a']
,但是应该注意,它永远不会导致
键错误
-对于不存在的键,它会返回
None
。@havelock是的,他是这么说的。使用x.get而不是x['a']。要使上述内容更一般化,请使用
super(self.\uu class\uuuu,self)
而不是
super(BaseCheckoutForm,self)
一个提示:通过
x不是None来检查
None
<对于几个可能有效的值(如空集合(包括字符串)、零(-等效数字)、明显的
False
,code>not x
True
)。有人会说,它更明确/可读;)我认为如果用户:
而其他值无论如何都是无效的(False,,[]),则使用
更容易阅读。那么在我的情况下可以吗?只要你同意作为
用户
传入的任何值都不等同于逻辑
被忽略,那么可以。然而,在许多情况下,你可能会被这烧死。只是要意识到其中的差异!
 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)