保留上下文的细节以及我关心的原因......
可以这样做:
class IsThisOk(object):
def __init__( self, **kwargs ):
for k in kwargs:
setattr( self, k, kwargs[k] )
obj = IsThisOk( apples=2 , oranges=2 )
因为我总是将其视为:
class OptionB(object):
apples = None
oranges = None
"""class defaults"""
def __init__( self, **kwargs ):
for k in kwargs:
setattr(self,k,kwargs[k])
b = OptionB( apples=2 , oranges=2 )
=====
编辑:
我最初在上面有这个,这是我不应该有的......
class OptionA(object):
"""set self.k but with class defaults"""
apples = None
oranges = None
def __init__( self, **kwargs ):
for k in kwargs:
self.k = kwargs[k]
a = OptionA( apples=2 , oranges=2 )
这一切都来自我试图优化一些代码。
我也注意到了::
for k in kwargs:
setattr( self, k, kwargs[k] )
比
快一点 for k,v in kwargs.iteritems():
setattr( self, k, v )
答案 0 :(得分:5)
正如delnan评论的那样,IsThisOk
或OptionA
都不会像你所展示的那样奏效。这是因为self.k = kwargs[k]
相当于setattr(self, "k", kwargs[k])
,而不是您在OptionB
中使用的所需电话。
另一种解决方案可能是使用标准库中namedtuple
模块的collections
类工厂:
>>> from collections import namedtuple
>>> OptionC = namedtuple("OptionC", ["apples", "oranges"])
>>> c = OptionC(2, 2) # you can also use keyword arguments, if you wish
>>> print(c)
OptionC(apples=2, oranges=2)
此选项的限制是OptionC实例将是不可变的,就像它的父类tuple
一样。也就是说,在创建实例后,您将无法执行c.apples = 5
。
要回答标题中的问题,不,没有必要在类定义中定义默认变量。事实上,我认为这是气馁的。如果您希望类构造函数有可选参数,请在__init__
方法的定义中给出它们的默认值:
class OptionD:
def __init__(apples=None, oranges=None):
self.apples = apples
self.oranges = oranges
答案 1 :(得分:-3)
编辑正如评论中所述,这几乎是不该做的一个例子。
...
for k in kwargs:
exec('self.{}={}'.format(k,kwargs[k]))
...