我从教程中创建了这段代码但很难理解一个关键概念:'next'如何变得等于字符串“s”? self.start如何引用该字符串?
import sys
class DemoClass(object):
def __init__(self, start): # executes once!
self.start = start
print "_init_"
def play(self): # executes once!
next = self.start
print "next"
while True:
attr = getattr(self, next) #get attribute of the class
next = attr()
def s(self): # these methods start calling each other once executed
print "s"
return 't'
def t(self):
print "t"
i = raw_input(">")
if i == 's': # if user input 'i' is equal to 's', call func "s"
return "s"
elif i == 'v':
return "v"
else:
exit(0)
def v(self):
print "v"
return 's'
a = DemoClass("s")
a.play()
答案 0 :(得分:2)
第一次初始化类时,将入口点设置为函数spaghetti。 play()
然后根据start
的内容启动执行链。 getattr(self, next)
实际上将获得对具有该名称的类成员的引用,next=attr()
将调用getattr
返回的成员,并将该调用返回的值分配给next
。
对于方法,当next为's'时,s
将执行,然后next
将为't',这将导致t
被检索并执行。 t
中有raw_input
个电话,这意味着用户可以控制下一个电话。如果用户输入's',t
将返回's',如果他们输入'v',t
将返回'v',否则程序将退出。 v
只会导致play
循环回s
。
这是一堆无意义的逻辑,没有任何上下文,为什么你可能想要一个这样结构化的程序,所以我可以看出为什么它会让人困惑。
答案 1 :(得分:1)
对于你的第一个问题:getattr在这种情况下返回实例的属性方法s
,然后你用attr()
执行它,getattr将一个实例和一个属性作为字符串并返回属性对象。
答案 2 :(得分:1)
我发现你的代码有些令人困惑,但基本上这里发生的事情与Python类的功能有关。因为Python函数是本地作用域的,为了对类对象本身进行任何修改,类的每个方法都将类本身作为其第一个参数,通过名为“self”的约定。该对象将所有变量和方法作为属性。
还有一个特殊的__init__
函数,在声明该类的实例时会调用它。这也需要self
作为第一个参数,然后是你想要的任何其他自定义参数。
至于您的问题,以下简化代码是's'
分配给next
的方式:
class DemoClass(object):
def __init__(self, the_input):
# The input on the class declaration is assigned to the
# class attribute 'start'
self.start = the_input
def play(self):
self.next = self.start
joe = DemoClass('s')
print joe.start # prints 's'
print joe.next # raises error, since joe.next hasn't been defined
joe.play()
print joe.next # also prints 's', now that self.next has been defined
答案 3 :(得分:1)
'next'如何变得等于字符串“s”
每当调用任何对象方法时,方法的第一个参数将自动设置为对象本身。它通常被称为self
。
当您执行a = DemoClass("s")
时,会使用参数DemoClass::__init__
和self
调用's'
。然后self.start = start
将's'
分配给self.start
。
当您致电a.play()
时,该对象将作为第一个参数发送至play
。 next = self.start
self.start
分配's'
__init__
分配给next
的{{1}}。