def drawPoint(direction, x):
turtle.(direction[x])(1)
turtle.forward(1)
x = x + 1
drawPoint(direction, x%2)
def main():
x = 0
myTurtle = turtle.Turtle()
myWindow = turtle.Screen()
direction = ['right', 'left', 'up', 'down']
drawPoint(direction, x)
例如我试图写龟。(方向[x])。 direction是一个字符串数组,字符串是turtle命令。因此,如果我遍历方向数组,每次调用drawPoint时都会更改turtle命令。
答案 0 :(得分:0)
我可以看到你在这里要做的事情:
turtle.(direction[x])(1)
您希望使用direction[x]
中的字符串作为方法的名称。您可能不应想要这样做,但可以。只是不直接;你必须使用getattr
函数:
getattr(turtle, direction[x])(1)
无论如何,使用getattr
通常不是一个好主意。更好的想法是将方法存储在列表中,而不是它们的名称中。像其中一个:*
direction = [myTurtle.right, myTurtle.left, myTurtle.up, myTurtle.down]
direction = [turtle.Turtle.right, turtle.Turtle.left, turtle.Turtle.up, turtle.Turtle.down]
第一个版本创建一个绑定方法列表,它知道它们附加到哪个对象(myTurtle
),因此您只需调用direction[0](1)
即可。第二个创建未绑定方法的列表,它们不知道它们附加到哪个对象;你必须像参数direction[0](myTurtle, 1)
一样明确地传递它。我认为后者在这种情况下更有意义,因为下一点,但两者都是完全有效的。
你在这里也遇到了另一个问题:turtle
不是你的龟对象,它是一个模块。您需要一些对象才能使用,但drawPoint
中没有。幸运的是,您在myTurtle
中创建了一个名为main
的名称,因此您只需将其传递给drawPoint
。
最后,如果你想迭代,请使用循环,而不是递归调用自己。否则,在第1000个循环中,你将得到一个异常,你的程序将以一个丑陋的堆栈跟踪退出。**
所以:
def drawPoint(myTurtle, direction, x):
while True:
direction[x](myTurtle)(1)
myTurtle.forward(1)
x = x + 1
x %= 2
def main():
x = 0
myTurtle = turtle.Turtle()
myWindow = turtle.Screen()
direction = ['right', 'left', 'up', 'down']
drawPoint(myTurtle, direction, x)
另一个漂亮的技巧。如果要永久循环遍历列表,而不是跟踪索引并使用%
重置为0,则可以使用cycle
函数。在这种情况下,我们只想绕过direction
的前两个元素,因此我们将使用切片:
import itertools
def drawPoint(myTurtle, direction, x):
for dir in itertools.cycle(direction[:2]):
dir(myTurtle)(1)
myTurtle.forward(1)
*在Python中,所有是一流的值 - 模块,类,对象,函数,绑定和非绑定方法等。这意味着您可以将其粘贴在列表中,将它传递给函数,无论你想要什么。
**每次调用另一个函数时,它都会在堆栈上推送另一个帧。当你返回时,它会从堆栈中弹出一个框架。但是如果你的函数在返回之前调用另一个函数,并且在返回之前调用另一个函数,依此类推,你最终会溢出堆栈。为了避免较低级语言的恶意崩溃(和安全漏洞),Python不会让你走得那么远,并且当你获得1000深度时会引发异常。 (如果你已经习惯了另一种语言,例如,Scheme,这让你感到惊讶,那是因为Scheme会进行尾调用消除,而Python则不然;更常见的是,Scheme旨在鼓励尽可能多的递归,而Python旨在劝阻它。)