Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 仅接受与其属性匹配的命名参数的构造函数_Python_Python 2.7_Constructor - Fatal编程技术网

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

Python 仅接受与其属性匹配的命名参数的构造函数,python,python-2.7,constructor,Python,Python 2.7,Constructor,我希望在Python 2.7中有一个类,其中: 我可以将一个或多个命名参数传递给构造函数,这些参数初始化它们相应的属性 如果这些命名参数中的任何一个不是类的指定属性,则会引发异常 构造时未传递任何命名参数的每个属性的值均为None 我有一些工作,但我怀疑一定有一个更容易和/或更python的方式-有吗 class Foo: bar = None baz = None def __init__(self, **kwargs): for k in kwargs:

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

  • 我可以将一个或多个命名参数传递给构造函数,这些参数初始化它们相应的属性
  • 如果这些命名参数中的任何一个不是类的指定属性,则会引发异常
  • 构造时未传递任何命名参数的每个属性的值均为
    None
  • 我有一些工作,但我怀疑一定有一个更容易和/或更python的方式-有吗

    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
    
    …然后引发了一个异常,这就是我想要的,因为它捕获了“bazz”输入错误


    看来我有些东西在工作,但我不知道我不知道的是什么,所以:有没有更好/更容易/更具Python风格的方法?

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

    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,)
    
    \uuuu init\uuuu
    中,只需使用
    pop
    检索所需的关键字参数并将其从dict中删除。如果仍有任何参数,则引发一个错误,指示找到了哪些额外参数


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

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

    使用?@Ryan Haining最初我打算使用namedtuple,但如果我理解正确,它要求在构造函数中传递所有属性,我希望能够选择性地省略一些属性。另外,我以后可能想向类中添加方法,因此为了将来的验证,命名元组并不理想。您可以对命名元组进行子类化。您确定要将
    foo
    baz
    作为类属性吗?@chepner像这样?问题是它不是很干,因为“颜色”是重复的。有没有一种不重复属性名称的方法?FWI,我不太关心一个类相对于一个命名的双倍的性能成本,谢谢-这看起来更好。关于这样做是好主意还是坏主意和/或是蟒蛇术,有什么评论吗?我这样问是因为我(未受过教育)的假设是,这将是一个常见的需求,因此将有一个“内置”解决方案,或者至少是一个有良好文档记录的解决方案。但似乎没有,这让我质疑这个假设,然后质疑我的需求的有效性。你能解释一下吗?换句话说,列出的3个需求中,哪一个是不寻常的?#2是最不寻常的,但这只是因为语言没有类实例所需属性集的概念。