可以不定义类默认值吗?

时间:2013-02-02 21:18:43

标签: python

保留上下文的细节以及我关心的原因......

可以这样做:

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 )

2 个答案:

答案 0 :(得分:5)

正如delnan评论的那样,IsThisOkOptionA都不会像你所展示的那样奏效。这是因为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]))
...