你怎么能设置python中的variables参数(kwargs)的类属性

假设有一个具有构造函数(或其他函数)的类,它接受可变数量的参数,然后有条件地将它们设置为类属性。

我可以手动设置它们,但似乎variables参数在python中已经足够普遍,应该有一个常见的习惯用法。 但我不知道如何dynamic地做到这一点。

我有一个使用eval的例子,但这不是安全的。 我想知道这样做的正确方法 – 也许与lambda?

class Foo: def setAllManually(self, a=None, b=None, c=None): if a!=None: self.a = a if b!=None: self.b = b if c!=None: self.c = c def setAllWithEval(self, **kwargs): for key in **kwargs: if kwargs[param] != None eval("self." + key + "=" + kwargs[param]) 

你可以使用setattr方法:

 class Foo: def setAllWithKwArgs(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) 

有一个类似的getattr方法来检索属性。

这不是更容易吗?

 class Bar(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) 

然后你可以:

 >>> bar = Bar(a=1, b=2) >>> bar.a 1 

并用类似的东西:

 allowed_keys = ['a', 'b', 'c'] self.__dict__.update((k, v) for k, v in kwargs.iteritems() if k in allowed_keys) 

你可以事先过滤钥匙。

我提出了一个fqxp的答案,除了允许的属性之外,还可以为属性设置默认值

 class Foo(): def __init__(self, **kwargs): # define default attributes default_attr = dict(a=0, b=None, c=True) # define (additional) allowed attributes with no default value more_allowed_attr = ['d','e','f'] allowed_attr = list(default_attr.keys()) + more_allowed_attr default_attr.update(kwargs) self.__dict__.update((k,v) for k,v in default_attr.items() if k in allowed_attr) 

这是Python 3.x代码,对于Python 2.x,您至less需要一次调整, iteritems()代替items()

这里的大多数答案并不包括将所有允许的属性初始化为一个默认值的好方法。 所以,要添加@fqxp和@mmj给出的答案:

 class Myclass: def __init__(self, **kwargs): # all those keys will be initialized as class attributes allowed_keys = set(['attr1','attr2','attr3']) # initialize all allowed keys to false self.__dict__.update((key, False) for key in allowed_keys) # and update the given keys by their given values self.__dict__.update((key, value) for key, value in kwargs.items() if key in allowed_keys) 
 class SymbolDict(object): def __init__(self, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) x = SymbolDict(foo=1, bar='3') assert x.foo == 1 

我调用了SymbolDict类,因为它本质上是一个使用符号而不是string操作的字典。 换句话说,你做的是x.foo而不是x['foo']但是在封面之下它是真的一样的事情发生。

他们可能是一个更好的解决scheme,但是我想到的是:

 class Test: def __init__(self, *args, **kwargs): self.args=dict(**kwargs) def getkwargs(self): print(self.args) t=Test(a=1, b=2, c="cats") t.getkwargs() python Test.py {'a': 1, 'c': 'cats', 'b': 2} 

这一个是最简单的通过larsks

 class Foo: def setAllWithKwArgs(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) 

我的例子:

 class Foo: def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) door = Foo(size='180x70', color='red chestnut', material='oak') print(door.size) #180x70 

我怀疑在大多数情况下使用命名参数(为了更好的自我logging代码)可能会更好,所以它可能看起来像这样:

 class Foo: def setAll(a=None, b=None, c=None): for key, value in (a, b, c): if (value != None): settattr(self, key, value)