7

Python 中的构造函数通常如下所示:

class SomeClass:
    def __init__(self, a, b = None, c = defC):
        self.a = a
        self.b = b or []
        self.c = c

是否有一个快捷方式,例如简单地定义__init__(self,**kwargs)和使用键作为属性self

4

3 回答 3

9

我见过的一个成语是self.__dict__.update(locals()). 如果您在方法的开头运行它,这将使用参数更新对象的字典(因为这些是方法开头的唯一局部变量)。如果你通过**kwargs你可以做到self.__dict__.update(**kwargs)

当然,这是一种脆弱的方法。如果您不小心传入了掩盖现有属性的参数,则可能会导致令人费解的错误。例如,如果您的类有一个.doSomething()方法并且您不小心将其传递doSomething=1给了构造函数,那么如果您稍后尝试调用该方法,它将覆盖该方法并导致错误。出于这个原因,最好不要这样做,除非在某些微不足道的情况下(例如,某种代理对象,其唯一目的是充当包含一些属性的“包”)。

于 2012-08-30T06:33:33.477 回答
6

是的:

class SomeClass:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
于 2012-08-30T06:31:10.200 回答
6

一个问题

self.__dict__.update(locals())

是它包括self,所以你得到self.self。最好过滤selflocals()

例如。

vars(self).update((k,v) for k,v in vars().items() if k != 'self')

您可以防止使用此变体意外覆盖方法

vars(self).update((k,v) for k,v in vars().items()
                   if k != 'self' and k not in vars(self))

如果您不希望它静默失败,您也可以像这样预先检查

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')
于 2012-08-30T06:38:32.660 回答