Python - 在super()调用后使用可选kwarg时,最简洁的__init__重写方法是什么?
我很喜欢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 个回答
60
我通常也是像你这样做。不过,你可以通过给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)