仅接受与其属性匹配的命名参数的构造函数

时间:2015-11-19 01:56:46

标签: python python-2.7 constructor

我希望在Python 2.7中有一个类,其中:

  1. 我可以向构造函数传递一个或多个命名参数,这些参数初始化它们相应的属性
  2. 如果任何这些命名参数不是该类的指定属性,则会引发异常
  3. 在构造中未传递任何命名参数的每个属性都具有值None
  4. 我有一些工作,但我怀疑必须有更容易和/或更多的pythonic方式 - 是吗?

    class Foo:
       bar = None
       baz = None
       def __init__(self, **kwargs):
    
          for k in kwargs:
             getattr(self, k)
    
          vars(self).update(kwargs)
    

    然后我可以做

    >>> f = Foo(bar = 3)
    >>> f.bar
    3
    >>> not f.baz
    True
    

    如果我这样做

    >>> f = Foo(bar = 3, bazz = 5) # 'bazz' is a typo
    

    ..然后提出了一个异常,这就是我想要的,因为它抓住了这个问题。错字。

    所以看起来我有一些工作,但我不知道我不知道什么,所以:有更好/更容易/更pythonic的方式吗?

1 个答案:

答案 0 :(得分:1)

首先,您的类应该在Python 2中显式扩展object

class Foo(object):

    def __init__(self, **kwargs):
        for arg in ["bar", "baz"]
            value = kwargs.pop(arg, None)
            setattr(self, arg, value)

        if kwargs:
            invalid_args = ", ".join(kwargs)
            raise ValueError("Invalid keyword argument(s): %s" % (invalid_args,)

__init__中,只需使用pop检索预期的关键字参数,然后将其从dict中删除。如果仍有任何参数,则引发错误,指出找到了哪些额外参数。

除非你要设置很多变量,否则我发现跳过循环并单独设置每个变量更具可读性。

def __init__(self, **kwargs):
    self.bar = kwargs.pop("bar", None)
    self.baz = kwargs.pop("baz", None)
    if kwargs:
        ...