2012-02-16 48 views
4

我已经完成了一些阅读,并且无法完全按照我的意愿去理解它。我正在一点点“选择自己的冒险”,从LPTHW教程游戏,以下是完整的脚本:http://codepad.org/YWVUlHnU__init__的用途

什么我不明白的是:

class Game(object): 

    def __init__(self, start): 
     self.quips = [ 
      "You died. Please try again.", 
      "You lost, better luck next time.", 
      "Things didn't work out well. You'll need to start over." 
      "You might need to improve your skills. Try again." 
     ] 
     self.start = start 

我明白咱”重新创建一个类,但为什么定义__init__?后来我做了一些像print self.quis[randint(0, len(self.quips)-1)]这样的打印quips中四个字符串之一的东西,但为什么我不会创建一个叫做quips的函数呢?

回答

15

当调用Game("central_corridor"),创建一个新的对象和Game.__init__()方法被称为与该新对象作为第一个参数(self)和"central_corridor"作为第二个参数。由于您写了a_game = Game(...),因此您已分配a_game来引用该新对象。

这个图形可以使这个过程更容易理解:

Python object creation

注:由Python的提供__new__方法。它创建了作为第一个参数给出的类的新对象。内置的__new__方法对剩余的参数不做任何处理。如果需要,可以覆盖__new__方法并利用其他参数。

实践理性__init__()存在于你的程序设置在你创建(你叫a_game之一)的Game实例start属性,以便于第一次调用在你想要的位置a_game.play()开始。

你说得对quips。没有理由在__init__()中设置quips。你可以只让一个类属性:

class Game(object): 
    quips = ["You died. Please try again.", 
      "You lost, better luck next time.", 
      "Things didn't work out well. You'll need to start over." 
      "You might need to improve your skills. Try again." ] 
    def __init__(self, start): 
     self.start = start 
+0

我想如果我创建了“Game”类的实例,我使用的任何属性都将决定游戏的开始位置。因此,如果我想通过在游戏类中的'laser_weapon_armory'函数开始游戏,我会做'a_game = game(“laser_weapon_armory”)'然后''a_game.play()'。 '__init__'与这个有什么关系? – ZCJ 2012-02-16 21:06:45

+0

__init__方法设置对象的基本状态......想象一下,如果需要先连接到数据库并首先下载一些数据以准备好自己,那么在做其他事情之前,您应该在__init__中执行此操作。这就像是要从经销商处购买汽车......没有__init__,你会得到一个没有车轮,没有引擎的汽车物体,但如果你愿意,你仍然可以car.drive()。 – michaelfilms 2012-02-16 21:25:20

+1

@ZCJ当你写'Game(“laser_weapon_armory”)'时,实际发生的是一个新的'Game'实例被创建,我们称它为'obj'(它现在真的没有名字),然后Python _automatically_运行'Game .__ init __(obj,“laser_weapon_armory”)'并返回'obj'(你最终分配给名字'a_game')。 '__init__'将'obj.start'设置为''laser_weapon_armory“''。当你运行'a_game.play()'时,实际发生的事情是Python正在运行'Game.play(a_game)''self'参数被'a_game'填充,所以'self.start'是''laser_weapon_armory “'当你调用'a_game.play()'时。 – 2012-02-16 21:52:10

1

__init__作为构造函数在这里。所以当游戏实例创建时,调用__init__方法。如果您定义了另一种方法来设置调查,则必须明确调用它。

+0

严格地说,'__new__'是构造和'__init__'是“initializator”。 – glglgl 2013-09-28 09:06:36

5

更广泛地说__init__和Python类的不太知名的,往往更危险__new__方法有做初始化的对象的状态的工作。

对于您的特定对象,它并不是真正必要的,我想有很多非常简单的数据存储类可以认为是不需要初始化的,但使用python进行更深层次编程的实际情况是,几乎每一个复杂类需要初始化为其基本状态。

另外很大的原因就是让你的类多用途:

class Foo(object): 
    def __init__(self, word_of_power="Ni"): 
     self.fact = "We are the knights who say %!" % word_of_power 

>>> f = Foo() 
>>> w = Foo("No!") 
>>> print f.fact 
"We are the knights who say Ni!" 
>>> print w.fact 
"We are the knights who say No!" 
+0

通过“多用途”,你的意思是我可以使用这个类来创建像Foo()这样的实例,以及具有像Foo(“No!”)这样的属性的实例吗?你是说,使其多用途的好处是,这两个都可以工作? – ZCJ 2012-02-16 22:22:13

+0

@ZCJ,为了保持术语的正确性,请注意,在Foo(“No!”)语句中,“No!”不是“属性”。这是一个_argument_,它和任何函数的参数一样。事实上,将'Foo'想象成一种特殊的函数会带来一些帮助,它会接收一些参数并返回一个'Foo'类型的对象。 'self.fact',另一方面,_is_属性。 – senderle 2012-02-16 22:41:49

+0

好的,非常感谢您的澄清 - 锤击术语是我正在努力的。因此,在你的响应中'w.fact'是一个属性,但是当变量'f'和'w'分配给'foo'的不同实例时,'foo'可以在括号内引用一个参数,因为类允许它。听起来对吗? – ZCJ 2012-02-16 23:00:25