具有非None类属性的类的新实例?

Log*_*bby 4 python class-instance-variables python-2.7

我有一个Python类,其class属性设置为除了None.创建新实例时,对该属性所做的更改将在所有实例中持续存在.

这里有一些代码可以理解这一点:

 class Foo(object):
   a = []
   b = 2

 foo = Foo()
 foo.a.append('item')
 foo.b = 5
Run Code Online (Sandbox Code Playgroud)

正如人们所期望的那样使用foo.a回报['item']foo.b回报5.

当我创建一个新的实例(我们叫它bar),使用bar.a收益['item']bar.b回报5,太!但是,当我最初设置所有类属性None然后将它们设置为任何内容时__init__,如下所示:

 class Foo(object):
   a = None
   b = None

   def __init__(self):
     self.a = []
     self.b = 2
Run Code Online (Sandbox Code Playgroud)

bar.a返回[]bar.b返回2时使用foo.a返回['item']foo.b返回5.

这是假设工作的方式吗?在我编写Python的3年里,我显然从未遇到过这个问题,并希望得到一些澄清.我也无法在文档中的任何地方找到它,所以如果可能的话,给我一个很好的参考.:)

NPE*_*NPE 7

是的,这是应该如何工作的.

如果ab属于实例Foo,那么正确的方式做到这一点是:

class Foo(object):
   def __init__(self):
     self.a = []
     self.b = 2
Run Code Online (Sandbox Code Playgroud)

下面的品牌ab属于类本身,因此所有实例共享相同的变量:

class Foo(object):
   a = []
   b = 2
Run Code Online (Sandbox Code Playgroud)

当你混合使用这两种方法时 - 正如你在第二个例子中所做的那样 - 这不会增加任何有用的东西,只会引起混淆.

值得一提的一个警告是,当您在第一个示例中执行以下操作时:

foo.b = 5
Run Code Online (Sandbox Code Playgroud)

你没有改变Foo.b,你正在为foo那个"阴影" 添加一个全新的属性Foo.b.当你这样做时,既不改变bar.b也不Foo.b改变.如果您随后执行此操作del foo.b,则会删除该属性并foo.b再次参考Foo.b.