Is there a shortcut for `self.somevariable = somevariable` in a Python class constructor?
python中的构造函数通常如下所示:
1 2 3 4 5
| class SomeClass:
def __init__(self, a, b = None, c = defC):
self.a = a
self.b = b or []
self.c = c |
是否有这样的快捷方式,例如简单地定义__init__(self,**kwargs)并将键用作self的属性?
- 我知道一个人不应该在一个构造器中有这么多不同的参数,而这些参数在字典中是无法逻辑收集的,这个问题更是出于好奇。
一idiom self.__dict__.update(locals())是我见过。如果你运行它right at the beginning of the method,the s this will object'词典更新(因为那些Arguments are with the the only at the beginning of the method .)。如果你在**kwargsYou can do self.__dict__.update(**kwargs)通行证。P></
of this is a当然,脆弱的方法。它可以导致错误的puzzling an argument中如果你accidentally通,masks安现有的属性。如果你为审级,你在.doSomething()method has to the accidentally通doSomething=1构造函数,它会重写the method和安误差原因,以后如果你试图呼叫的方法。for this reason to do this better not是平凡的(除了在一定的案例,如sort of some代理对象只需要谁的目的是作为控股公司的一些属性的"袋")。P></
- 我明白了,所以我应该在大多数情况下避免这种情况,然后至少使用一些只产生**kwargs的函数,这些函数已经在self.__dict__中了。相关:self.__dict__.update(**kwargs)是好的还是差的款式?
是的:P></
1 2 3
| class SomeClass:
def __init__(self, **kwargs):
self.__dict__.update(kwargs) |
- 哇,太快了!
- 这是可行的,但正如布伦巴恩和格尼布尔所说,可能会有非常不方便的副作用。
- 不!不方便的副作用只有在您选择locals()解决方案时才会发生。使用**kwargs时不显示!
- 是的,我指的是当a_method是之前在SomeClass中定义的方法时,可以执行类似brokenInstance = SomeClass(a_method = [])的操作,也就是说,可以意外地修改不应该修改的类属性。需要实现一些白名单或黑名单机制来防止这种情况发生。
有一个问题P></
1
| self.__dict__.update(locals()) |
它包括selfis that self.self,知道你得到。它会是更好的selfout of locals()to filterP></
EG。P></
1
| vars(self).update((k,v) for k,v in vars().items() if k != 'self') |
你可以用这个方法对accidentally defend overwriting变化P></
1 2
| vars(self).update((k,v) for k,v in vars().items()
if k != 'self' and k not in vars(self)) |
如果你不想要它,你可能会silently检查失败,也beforehand like thisP></
1 2 3
| if any(k in vars(self) for k in vars()):
raise blahblah
vars(self).update((k,v) for k,v in vars().items() if k != 'self') |
- 有趣的一点。因此,像vars(self).update((k,v) for k,v in vars(self).items())这样的东西可能会确保只设置已经存在的属性,然后使用一些代码警告(甚至引发异常)试图设置不应该设置的属性。尽管我想这仍然允许重新定义类方法,正如Brenbarn所说的那样。
- @Tobias,我添加了一个示例以避免重写类方法
- 谢谢!现在还太早了,我笑着念了any(km-/ok,所以稍微修改一下,就可以定义默认参数了。但这确实表明,在大多数情况下,人们应该坚持使用self.var1 = var1。
- @托比亚斯,是的,通常解释更好。你怎么知道把None翻译成[]呢?
- 仅凭这一点可能是不这么做的最短原因。虽然一些for k in kwargs.keys()和来自**kwargs副本的关键字white-/blacklist和pop可能提供一些灵活性,并以某种方式保持可读性。但是,再说一次,我想不出一个实际的应用程序有超过,比方说,一个构造函数的十个命名参数,在这些参数中,使用@classmethod定义不同的构造函数是不够的。