首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Python中声明实例变量的默认值?

如何在Python中声明实例变量的默认值?
EN

Stack Overflow用户
提问于 2010-04-21 16:11:41
回答 5查看 139.9K关注 0票数 101

我是否应该像这样给我的类成员提供默认值:

class Foo:
    num = 1

或者像这样?

class Foo:
    def __init__(self):
        self.num = 1

this question中我发现在这两种情况下,

bar = Foo()
bar.num += 1

是一个定义良好的操作。

我知道第一个方法会给我一个类变量,而第二个不会。但是,如果我不需要类变量,而只需要为我的实例变量设置一个默认值,那么这两种方法是否一样好?或者他们中的一个比另一个更“蟒蛇”?

我注意到的一件事是,在Django教程中,they use the second method to declare Models.个人认为第二种方法更优雅,但我想知道什么是“标准”方法。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-04-21 17:02:25

扩展bp的答案,我想向您展示他所说的不可变类型是什么意思。

首先,这是可以的:

>>> class TestB():
...     def __init__(self, attr=1):
...         self.attr = attr
...     
>>> a = TestB()
>>> b = TestB()
>>> a.attr = 2
>>> a.attr
2
>>> b.attr
1

然而,这只适用于不可变(不可改变)的类型。如果缺省值是可变的(意味着它可以被替换),那么就会发生这种情况:

>>> class Test():
...     def __init__(self, attr=[]):
...         self.attr = attr
...     
>>> a = Test()
>>> b = Test()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[1]
>>> 

请注意,ab都有一个共享属性。这通常是不必要的。

当类型可变时,这是定义实例变量默认值的Pythonic方法:

>>> class TestC():
...     def __init__(self, attr=None):
...         if attr is None:
...             attr = []
...         self.attr = attr
...     
>>> a = TestC()
>>> b = TestC()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[]

我的第一段代码之所以有效,是因为对于不可变类型,只要您需要,Python就会创建一个新的实例。如果您需要将1加到1,Python会为您创建一个新的2,因为旧的1是不能更改的。我相信,这主要是为了散列。

票数 144
EN

Stack Overflow用户

发布于 2010-04-21 16:35:26

使用类成员给出默认值效果很好,只要你只对不可变值小心。如果你试图用列表或字典来做这件事,那将是非常致命的。它还适用于实例属性是对类的引用的情况,只要缺省值为None即可。

我看到这种技术在repoze中得到了非常成功的应用,这是一个运行在Zope之上的框架。这样做的好处不仅在于,当您的类持久化到数据库时,只需要保存非默认属性,而且当您需要向模式中添加新字段时,所有现有对象都会看到具有默认值的新字段,而不需要实际更改存储的数据。

我发现它在更通用的编码中也能很好地工作,但它是一个风格问题。使用任何你最满意的东西。

票数 6
EN

Stack Overflow用户

发布于 2010-04-21 16:24:09

使用类成员作为实例变量的默认值并不是一个好主意,而且这是我第一次看到有人提到这个想法。它在您的示例中可以工作,但在许多情况下可能会失败。例如,如果值是可变的,在未修改的实例上改变它将改变默认值:

>>> class c:
...     l = []
... 
>>> x = c()
>>> y = c()
>>> x.l
[]
>>> y.l
[]
>>> x.l.append(10)
>>> y.l
[10]
>>> c.l
[10]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2681243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档