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.
精彩评论