开发者

How come a returned string can be interpreted as a function in python?

I was skimming through Learn python the hard 开发者_开发知识库way and I have come across a code snippet like below. But I did not understand what's behind it, a function basically returns a string that which it's class has a function of the same name. And it can call the function properly. Well, you will get what I mean when you look at the code.

Code:

from sys import exit
class Game(object):
    def __init__(self, start):
        self.start = start

    def play(self):
        next = self.start

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

    def a1(self):
        print "You are in a1, redirecting to a2"
        return 'a2'
    def a2(self):
        print "You are in a2, exiting"
        return 'death'
    def death(self):
        print 'You died'
        exit(0)


a_game = Game('a1')
a_game.play()


What you see is the result of the getattr() builtin. Python is a high level language and what's more, an interpreted one. Since all objects in python are basically constructed in memory in forms of hash-tables Python has a rather vast Reflection mechanism.

This means that Python can inspect and modify its own classes and objects in runtime and one of the ways to do so is the getattr() builtin. The getattr builtin retrieves the value of the member in the first argument, which name it receives as a string in the second argument. getattr(x, "y") is basically the same as x.y, but getattr also allows for a safer approach where a default value can be given if a member is not actually present: getattr(x, "y", "No such member"). If x has no member y then x.y would cause an AttributeError exception. On the other hand gettattr(x, "y", "No such member") would return the string "No such member" and no exception is raised.

In your case, the methods are placed in the next variable as strings and are accessed through the getattr() builtin placed into room. room() is then invoked and the next methods name is returned and stored into next. This repeats in the while loop until exit(0) is invoked in Game.death().

You should also have a look at setattr() and hasattr()


The trick is the getattr function. It gets an attribute from an object, given its name. The name is a string. the names of the methods (bound functions) are passed as the next variable, getattr gets the method, and the next line calls it, changing the next variable. It's basically a state machine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜