2013-02-02 32 views
0

节约方面的细节,为什么我不在乎......可以不定义类的默认值吗?

是没关系做到这一点:

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) 
+4

你知道那'self.k = ...'只是创建一个属性'k',不无论变量“k”包含什么名字的属性? (这是与使用'setattr'的版本比较。) – delnan

+0

这就是为什么我总是使用setattr ...我匆忙试图优化一些代码。 –

回答

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 
+0

谢谢。我所关心的真正问题是“不,不需要在类定义中定义默认变量。“ 我刚把代码快速扔到一起做了一个班级的默认值vs不是,并由于某种原因开始比较选项D的'self.k' –

+0

+1 –

-3

编辑正如评论说快,这是相当多的什么不该做的例子。

... 
for k in kwargs: 
    exec('self.{}={}'.format(k,kwargs[k])) 
... 
+5

Nooooo。如果某人传入值“'destroy_the_server()”'会怎么样? 'setattr'这样做*这样*更清洁和更安全。 – Matchu

+0

另外,*它甚至不工作*(对于非常简单和无害的值,如字符串或大多数用户定义的对象)。 – delnan

+0

谢谢你的解释。我使用python进行个人使用,并没有深入研究安全问题。我确实喜欢一些exec()动作:) – Octipi

相关问题