__init__ 是不是总是必要的?

5 投票
2 回答
7171 浏览
提问于 2025-04-17 23:36

好的。我看到有人在用这段代码,我明白它的意思,所以我也打算用它。
请问一定要有 __init__ 吗?

class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

a = A() 
a.method_a('Sailor!')

我难道不能直接这样做吗:

class A(object):
    def method_a(self):
        print "Hello, Sailor!"

a = A()
print a.method_a()

当我这样做的时候,确实能看到“Hello, Sailor!”这句话,但下面却出现了一个“None”。这和 __init__ 有关系吗?有人能解释一下吗。

2 个回答

4

如果你在创建对象的时候不需要设置任何属性或者进行其他初始化操作,那么可以放心地省略掉 __init__ 这个方法。你看到 None 的原因是因为你的 method_a() 方法没有返回任何值。所以当你打印它的时候,就会显示 None

如果你写成这样:

class A(object):
    def method_a(self):
        return "Hello, Sailor!"
a = A()
print a.method_a()

这时候你就不会看到 None 了,因为 method_a 返回的是一个字符串,然后你再调用 print 来显示这个字符串。

或者如果你写成这样:

class A(object):
    def method_a(self):
        print "Hello, Sailor!"
a = A()
a.method_a()

这次调用 method_a 会直接打印出字符串,但因为你没有打印这个结果(只是调用了它),所以你不会看到 None 的显示。

8

你问的问题和 __init__ 没什么关系。你可以按照第二个例子那样做,但它和第一个例子做的事情不一样。

在第一个例子中,它会打印“Hello”,后面跟着你传给方法的参数。你可以传入其他东西,让它打印不同的内容,而不仅仅是“sailor”:

>>> a.method_a('buddy!')
Hello buddy!

在第二个例子中,它总是打印“Hello, Sailor!” 你无法让它打印其他内容。

至于 __init__,在你的例子中,__init__ 并不是很有用,因为它只是设置了一个属性 x,这个属性对于每个对象都是相同的字符串。如果你想在创建每个对象时“设置”它,应该使用 __init__。在你的例子中,这种设置并不有趣,因为每个对象都是一样的。你并不必须使用 __init__,但通常来说,创建没有任何个体状态的对象是没有太大意义的。这里有一个更好的例子:

class Greeter(object):
    def __init__(self, greeting):
        self.greeting = greeting

    def greet(self, who):
        print self.greeting + ", " + who + "!"

然后你可以这样做:

>>> hello = Greeter("hello")
>>> hello.greet('sailor')
hello, sailor!
>>> howdy = Greeter('Howdy')
>>> howdy.greet('partner')
Howdy, partner!

在这里,当你创建一个 Greeter 时,你指定了问候语。这个问候语会和对象一起保存,并在它 greet 某人时使用。__init__ 的意义在于你可以创建多个问候者,每个问候者有不同的问候语。

注意,当我调用 greet 时,我仍然传入了要问候的人。所以问候语(在这个例子中是 hello 或 howdy)是在我创建对象时设置的,但每次我用这个对象去 greet 时,问候的人都是新的。

通常你会在代码中混合这两种信息。有些信息是“对象的一部分”,你会在 __init__ 中处理并存储在对象上。其他的则是更具体或临时的信息,你会在每次想要执行的任务中作为函数参数传入。两者之间的平衡取决于这个类的用途,但上面的例子应该能说明它们的区别。

另外,这两个例子都和你看到“None”被打印没有关系。dr_jimbob 已经解释了为什么会这样。

撰写回答