关于在Python中正确使用__init__

时间:2015-10-15 14:32:08

标签: python class object init

Python中关于这两个语句的语义差异是什么?

    class Person :
        age = 5

    class Person :

        def __init__(self):
            self.age = 5

如果我在两种情况下都实例化一个对象,例如

    mario = Person ()

在这两种情况下,mario的{​​{1}}都是5

那么,在需要使用age方法的情况下,如果对象在实例化后立即分配了属性,即使不使用__init__

2 个答案:

答案 0 :(得分:3)

__init__属性引用类实例的变量,在类下面意味着它是一个类变量。

当您使用例如变量列表时,这将非常重要:在类下面将使列表在 instantiations 之间共享,即如果您在类的一个实例中附加到该列表,该类的所有其他实例化也将“看到”列表中的附加项。

class Foo:
   x = []

a = Foo()
b = Foo()
a.x.append(1)

b.x == [1] # True

c = Foo()    # Even being created after 1 has been appended, still:
c.x == [1] # True

当您使用__init__时不是这种情况,“x”属性对于每个实例化都是唯一的。

答案 1 :(得分:2)

两者之间的区别在于,在上面的示例中,您正在创建一个类属性,而在init中,您正在创建一个实例属性。两者之间的区别在于:

class Foo():
    bob = "my name is bob"

print(Foo.bob)
# outputs "my name is bob"
class Foo():
    def __init__(self):
        self.bob = "my name is bob"

执行print(Foo.bob)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'bob'

要在init中访问bob,您必须实例化:

f = Foo()
print(f.bob)
# outputs "my name is bob"

这两个实现的进一步区别在于,class属性将在所有实例之间共享,而实例属性仅在您的实例中共享。

因此,对于__init__内部定义的任何内容,如果创建Foo的新对象,则不会对init内的变量进行任何更改,而是对Foo的其他实例进行更改。

但是,对于类属性,您更改的任何类属性都将在Foo的所有实例中更改。