类属性和实例属性有什么区别?

43 浏览
0 Comments

类属性和实例属性有什么区别?

这两种形式之间是否有任何有意义的区别:

class A(object):
    foo = 5   # some default value

VS.

class B(object):
    def __init__(self, foo=5):
        self.foo = foo

如果你创建了很多实例,这两种样式在性能或空间需求方面是否有差异?当你阅读代码时,你认为这两种样式的含义是否有显著的不同?

admin 更改状态以发布 2023年5月21日
0
0 Comments

不同点在于类上的属性被所有实例共享。实例上的属性是唯一的。

如果来自C ++,类上的属性更像是静态成员变量。

0
0 Comments

有一个重要的语义差异(除了性能考虑):

  • 当属性定义在实例上(通常是我们所做的),可以引用到多个对象。 每个对象都有完全独立的属性版本
  • 当属性定义在类上时,只有一个基础对象被引用,因此如果该类的不同实例的操作都尝试设置/(附加/扩展/插入等)该属性,则:
    • 如果该属性是内置类型(如int、float、布尔值、字符串),则一个对象的操作将覆盖(破坏)该值
    • 如果该属性是可变类型(如列表或字典),则会发生意外泄漏。

例如:

>>> class A: foo = []
>>> a, b = A(), A()
>>> a.foo.append(5)
>>> b.foo
[5]
>>> class A:
...  def __init__(self): self.foo = []
>>> a, b = A(), A()
>>> a.foo.append(5)
>>> b.foo    
[]

0