简体   繁体   English

如何在while循环中使函数更改变量?

[英]How to make a function change variables while in a while loop?

def lol(done, really_done):
    done = done + 1
    print(done)
    if done == 10:
        really_done = True

really_done = False
while really_done == False:
    done = 0
    lol(done, really_done)

so whenever I run this code, it does not change the value of done, it always stays at 1. I want it to change to 10 and stop the while loop. 因此,每当我运行此代码时,它都不会更改done的值,它始终保持为1。我希望将其更改为10并停止while循环。 I only want it in this type of module. 我只想要这种类型的模块。

The general problem is that you want to save the state of done and really_done across calls to lol . 普遍的问题是您希望在对lol调用中保存donereally_done的状态。 There are several ways to do this, so I'll toss in another possibility. 有几种方法可以做到这一点,所以我会尝试另一种方法。

A common way to keep state for a function is with a class: 保持函数状态的常见方法是使用类:

class Lol:

    def __init__(self, done=0, max_done=10):
        self.done = done
        self.max_done = max_done

    @property
    def really_done(self):
        self.done >= self.really_done

    def lol(self):
        self.done += 1

lol = Lol()
while not lol.really_done:
    lol.lol()

The really_done variable inside the lol function and the really_done variable at the module level live in different scopes (also commonly called namespaces ). really_done内部变量lol功能和really_done在模块级变量生活在不同的范围 (通常也称为命名空间 )。 The former is a local variable and the latter is a global variable . 前者是局部变量 ,后者是全局变量

def lol(done, really_done):
    done = done + 1               ---+
    print(done)                      |
    if done == 10:                   +--- the local scope (inside a `def`)
        really_done = True        ---+

really_done = False               ---+
while really_done == False:          |
    done = 0                         +--- the GLOBAL scope 
    lol(done, really_done)        ---+

You can not signal to the while loop that you want to exit in this way, because the local scope is isolated from the GLOBAL scope. 由于本地作用域与GLOBAL范围是隔离的,因此无法向您希望退出的while循环发出信号。 Instead, the function will need to signal to the caller that you're really done by using a return value: 取而代之的是,该函数需要通过使用返回值向调用方发送信号,告知您已完成操作:

def lol(done, really_done):
    done = done + 1
    print(done)
    if done == 10:
        really_done = True
    return done, really_done

done = 0
really_done = False
while really_done == False:
    done, really_done = lol(done, really_done)

Using the return value allows information from the local scope (function namespace) to be passed back out to the global scope (module namespace). 使用返回值允许将来自本地作用域(函数名称空间)的信息传递回全局作用域(模块名称空间)。 This is similar to the same way that passing in arguments to a function allows information from the outer scope (module namespace) to be received as information in the local scope (function namespace). 这类似于将参数传递给函数的方式,该方法允许将外部作用域(模块名称空间)中的信息作为本地作用域(功能名称空间)中的信息接收。

You are resetting the value of done everytime you run the loop. 您每次运行循环时都将重置done的值。 Not only that - you're trying to change the value a global variable, but is instead changing the value of a simple parameter, so lol(done) isn't actually doing anything. 不仅如此-您还尝试将值更改为全局变量,而是更改简单参数的值,因此lol(done)实际上并没有做任何事情。

If you want to keep it in a function, you should use the keyword global to indicate you're using the global variables: 如果要将其保留在函数中,则应使用关键字global来指示您正在使用全局变量:

def lol():
    global done
    global really_done

    done += 1
    really_done = done == 10

really_done = False
done = 0
while not really_done:
    lol()

This should work, but it's bad code - you shouldn't use global if it's not a real need . 这应该可以,但是它是不好的代码-如果不是真正的需要,则不应该使用global Not changing much of your code, you could use return to keep your code cleaner: 无需更改很多代码,可以使用return来保持代码更整洁:

def lol(done, really_done):
    done += 1
    really_done = done == 10

    return done, really_done

really_done = False
done = 0
while not really_done:
   done, really_done = lol(done, really_done)

That makes it a bit better. 这使它更好。 Yet, we could solve everything by simply looping a range with a for : 但是,我们可以通过用for循环一个range来解决所有问题:

done = 0
for n in range(10):
    done += 1
print(done)

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

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