Python 仅接受与其属性匹配的命名参数的构造函数
我希望在Python 2.7中有一个类,其中: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:
None
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是最不寻常的,但这只是因为语言没有类实例所需属性集的概念。