0

此处提出了类似的问题。然而,这些回答并没有真正帮助我理解程序的某些部分是如何工作的。程序如下:

from sys import exit
from random import randint

class Game(object):

    def __init__(self, start):
        self.pie = [ 'pie test']

        self.start = start

    def play(self):
        next_room_name = self.start
        while True:
            print "\n--------"
            room = getattr(self, next_room_name)
            next_room_name = room()

    def rooom(self):
        print "Test worked. good job"
        return "piez"

    def piez(self):
        print "pie room"
        exit(1)


a_game = Game("rooom")
a_game.play()

第一个问题是以下如何工作?

def play(self):
        next_room_name = self.start

        while True:
            print "\n--------"
            room = getattr(self, next_room_name)
            next_room_name = room()

我知道以下内容以某种方式生成了房间名称,因此程序可以转到它需要的位置。我只是没有看到它是如何发生的。

我的第二个问题是:

self.start = start

我有点理解 self.pie 正在做的事情。但我不确定 self.start = start 应该完成什么。再次感谢你的帮助。

4

2 回答 2

1

假设您有这样的课程:

class DummyClass(object):

    awesome = True

    def not_awesome(self):
        self.awesome=False

对此使用 getattr 完全等同于使用点语法,例如

dumb = DummyClass()
print getattr(dummy, "awesome") # True
print dummy.awesome # True

您也可以将其与方法一起使用:

dumb = DummyClass()
no_more_awesome = getattr(dummy, "not_awesome") # returns the not_awesome method of dummy
print dummy.awesome # True
no_more_awesome()
print dummy.awesome # False

因此,在您发布的代码片段中,getattr(self, next_room_name)获取带有名称的方法next_room_name并返回要调用的函数(绑定到自身)。您在这里使用变量而不是点语法,因为您事先不知道名称。考虑以下两个片段来获得这一点(与重叠有点混淆......对不起):

dummy = DummyClass()
awesome = "not_awesome"
print dummy.awesome # True
print getattr(dummy, awesome) # string with something like <bound method ... >
于 2012-08-20T00:47:52.390 回答
0

首先:对象初始化。Game("rooom")调用时,字符串绑定"rooom"到 的参数start__init__该语句this.start = start只是将字符串存储"rooom"在内部对象字典中,可通过this.start.

然后play()方法被调用:getattr在这个上下文中的用法定义了一个名为Pluggable Selector的模式。换句话说,不是显式说明要调用哪个方法,而是存储方法的名称是一个变量(next_room_name在这种情况下)。

要调用的第一个方法是rooom因为局部变量next_room_name(方法范围的局部变量)在 while 循环之前play被初始化。self.start

方法调用的返回值用于更新next_room_name变量,因此在rooom执行后,值变为"piez". 因此,下一个要调用的方法将是piez.

最后,当piez执行时,调用exit(1),因此解释器终止,不再执行代码。在这种情况下,没有更多代码执行的原因是sys.exit引发了一个SystemExit异常(参见文档),该异常在任何地方都没有被捕获。

于 2012-08-20T10:26:58.520 回答