简体   繁体   English

为什么在另一个函数中重新定义一个函数不起作用? (巨蟒龟)

[英]Why doesn’t redefining a function inside another function work? (Python Turtle)

I'm programming a game where enemy turtles (called badturt in the program) chase the user's turtle.我正在编写一个游戏,其中敌人的海龟(在程序中称为 badturt)追逐用户的海龟。 The user can make its turtle attack the enemy turtles by sending an attack (another turtle).用户可以通过发送攻击(另一只乌龟)使其乌龟攻击敌方乌龟。

In lvl 2, there are two enemy turtles chasing the user's turtle.在 lvl 2 中,有两只敌方海龟追逐用户的海龟。 To make one enemy turtle stop moving (after it is attacked/hit), I tried to redefine the function that makes the enemy turtle move, which was done inside another function.为了让一只敌龟停止移动(在它被攻击/击中后),我尝试重新定义使敌龟移动的函数,这是在另一个函数中完成的。 (I redefined it to None) (我将其重新定义为无)

attack = turtle.Turtle()
#...attributes

def turtleattack():
    global lvl
    global q
    global w
    global e
    #... positioning attack
    for i in range(75):
        attack.forward(10)
        if lvl == 1:
            Chase(badturt)
        if lvl == 2:
            Chase(badturt)
            Chase(badturt2)
        if lvl == 3:
            Chase(badturt)
            Chase(badturt2)
            Chase(badturt3)
        IfAttackHit()
bg.onkeypress(turtleattack, 'z')
bg.listen()


def Chase(bt): #makes bad turt (bt) chase turt
    bt.setheading(bt.towards(turt))
    bt.forward(11)

def StopChase(bt):
    global lvl
    global win
    #global Chase <---------------- program stops running if I write it in
    if lvl == 1:
        #...
    if lvl == 2:
        def Chase(bt):
            None
        if q == 2 and w == 2:
            lvl = 3
            writeinfo()
    if lvl == 3:
        def Chase(bt):
            None
        if q == 3 and w == 3 and e == 3:
            #... (winning the game)

def ChaseAgain(bt): #makes badturt chase again when it moves onto next lvl
    def Chase(bt):
        bt.setheading(badturt.towards(turt))
        bt.forward(11)
    Chase(bt)


def IfAttackHit():
    global win
    global lvl
    global q
    global w
    global e
    if lvl == 1:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 1
            StopChase(badturt) #<---- doesn't work
    if lvl == 2:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 2
            StopChase(badturt)
        if badturt2.distance(attack) < 20:
            badturt2.hideturtle()
            badturt2.goto(-300,350)
            attack.hideturtle()
            w = 2
            StopChase(badturt2)
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3


while True:
    if lvl == 1:
         while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            if q == 1:
                break
    break
    if lvl == 2:
        ChaseAgain(badturt) #make it move again
        ChaseAgain(badturt2)
        badturt.goto(300,350)
        badturt.showturtle()
        badturt2.showturtle()
        while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            Chase(badturt2)
    break
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3
        break

This didn't work.这没有用。 Was it because it was nested inside another function?是因为它嵌套在另一个函数中吗? Was StopChase() never called?从未调用过 StopChase() 吗? Did the function get redefined again so that the enemy turtle started moving again?函数是否再次被重新定义,以便敌方乌龟再次开始移动?

Also, my teacher told me that I had to write 'global Chase' to redefine it within another function, but when I do, the program stops running at that point - when I move my cursor over the turtle screen, it just shows the loading cursor, and nothing happens on the screen/it freezes.另外,我的老师告诉我,我必须编写“全局追逐”以在另一个函数中重新定义它,但是当我这样做时,程序会在那一点停止运行 - 当我将光标移到海龟屏幕上时,它只显示加载光标,屏幕上没有任何反应/它冻结。 (Was it wrong to do that, or is it an issue with the python program on my laptop?) (这样做是错误的,还是我的笔记本电脑上的 python 程序有问题?)

I also tried redefining Chase() so that badturt would only move forward 0 (essentially making it do nothing), but that didn't work either.我还尝试重新定义 Chase() 以便 badturt 只会向前移动 0(基本上使它什么都不做),但这也不起作用。

Please let me know what I'm doing wrong, or if there's another way to make badturt stop moving.请让我知道我做错了什么,或者是否有另一种方法可以让 badturt 停止移动。

When you redefine a non-class method the redefinition is permanent meaning it applies to everything.当你重新定义一个非类方法时,重新定义是永久性的,这意味着它适用于一切。 You probably don't want that.你可能不想那样。

What speaks against writing a condition inside of your Chase method?什么反对在您的 Chase 方法中编写条件?


There are various bad coding practices in your code:您的代码中存在各种不良的编码实践:

  • You should generally refrain from using global .您通常应该避免使用global You should create classes and instances of classes which have attributes and pass those instances around.您应该创建具有属性的类和类的实例并传递这些实例。
  • Methods aren't capitalized.方法没有大写。 Classes are capitalized.类是大写的。
  • You have some unreachable code due to break由于break您有一些无法访问的代码
  • Use pass instead of None when nothing is supposed to happen当不应该发生任何事情时,使用pass而不是None

Tin Nguyen is absolutely right and you should definitely follow his advices. Tin Nguyen 是绝对正确的,你绝对应该听从他的建议。 I'd just like to elaborate on your first question.我只想详细说明你的第一个问题。 Even if it could be bad, redefining your function using global should work.即使它可能很糟糕,使用 global 重新定义您的函数也应该有效。 Here is what I tried as a minimal example:这是我尝试的最小示例:

def f():
    print("f")

def g():
    global f
    def f():
        print("f_prime")

f()
g()
f()

When called I get:当被调用时,我得到:

f
f_prime

The explanation why your program stops must be elsewhere but you do not provide the error you faced, if any.您的程序停止的原因必须在其他地方,但您没有提供您遇到的错误(如果有)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM