【问题标题】:Python - Cleanest way to override __init__ where an optional kwarg must be used after the super() call?Python - 覆盖 __init__ 的最干净方法,其中在 super() 调用之后必须使用可选的 kwarg?
【发布时间】:2011-06-29 05:42:14
【问题描述】:

我喜欢 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 中对任何东西进行子类化的最棒的事情之一就是收集所有 argskwargs 并传递它进入你的子类。此外,这不支持源中的任何更改。

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)

感谢您的任何意见!

【问题讨论】:

  • 一个提示:通过x is not None 检查Nonenot xTrue 对于几个可能有效的值(如空集合(包括字符串)、零(等效数字)、显然是 False 等)。它也更明确/可读,有些人会说;)
  • 我认为仅使用if user: 更具可读性,并且其他值无论如何都无效(False,'',[])。那我的情况可以吗?
  • 只要您对作为user 传递的任何值都没有问题,这不等于逻辑True 被忽略,那么是的,没关系。但是,在许多情况下,您可能会因此而烦恼。请注意差异!

标签: python django


【解决方案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)

【讨论】:

  • 哦,非常好!我没有意识到流行音乐有第二个论点。你能告诉我我不经常pop吗?这有帮助!
  • @Yuji - 这当然是一个不错的功能!不要忘记您可以为dict.get 使用默认值,也可以避免KeyError s。 IE。如果您想在 'a' 不在 x 中时避免 KeyError,请使用 x.get('a', defaultvalue) 而不是 x['a']
  • @Joe 应该注意dict.get() has None as a default for 2nd argument,所以它永远不会导致KeyError - 它返回None 不存在的键。
  • @havelock 是的,他就是这么说的。使用 x.get 代替 x['a']。
  • 为了使上述更通用,请使用super(self.__class__, self)而不是super(BaseCheckoutForm, self)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多