在 while 循环中 运行 编码一次的最佳方法?

Best way to run code once within while loops?

我正在为 class 编写基于文本的角色扮演游戏,但陷入了代码困境...

from tkinter import *
...
runOnce = False
nextRun = False
"""Main Loop"""

while True:
    #New Game initialize
    if you.rName == None and runOnce == False:
        log("What is your name, adventurer?", eventLog)
        runOnce = True
    if you.rName != None and nextRun == False:
        log(f'What is your profession, {you.rName}?', eventLog)
        nextRun = True

#keypresses
playerInput.bind("<Return>", keyPress)
playerInput.bind("<FocusIn>", focusIn) 

top.update()
top.update_idletasks()

我目前所做的工作,但还有更多 if 语句类型的情况需要在继续下一个语句之前做出响应。循环是随着游戏 运行 不断更新 GUI。

如何在 while 循环中有效地编写需要响应一次的代码?

尝试在使用前检查您的参数是否为空。如果您正在寻找用户输入,您可以这样做:

userInput = None
while True:     
    userInput = input("Do the thing only once") if userInput is None else userInput
    ...

看到澄清,我同意这些类型的操作不应该属于循环的评论。这些应该是在主游戏循环之前收集的所有数据。

如果您循环遍历这些以验证输入,则可以使用单独的循环:

while not you.name:
   you.name = input('Enter name: ')
   # some additional validation text if necessary...

while not you.job:
   you.job = input('Enter job: ')
   # some additional validation text if necessary...    
while True:
   # main game loop requiring you.name, you.job

另一种方法有点做作。您可以在主循环之前预先定义这些函数并创建一个 RunOnce class 以仅执行一次这些函数:

class RunOnce(object):
    def __init__(self, func):
        self.func = func
        self.ran = False

    def __call__(self):
        if not self.ran:
            self.func()
            self.ran = True
    # once the function has been called, 
    # flip self.ran so it won't fire again.

# Decorate your functions with this special class
@RunOnce
def get_name():
    you.name = input('Enter Name: ')

@RunOnce
def get_job():
    you.job = input('Enter Job: ')

然后当您进入主游戏循环时:

while True:
    get_name()    # this will run once
    get_job()     # this too will run once
    get_name()    # this won't run anymore
    get_job()     # this neither.

这种方法的好处是它可以让您在必要时灵活地重新运行函数:

get_name()             # get_name.ran becomes True
get_name.ran = False   # reset the flag
get_name()             # this will run again.

我还是要说,重构代码会更好,这样只需捕获一次的内容就可以留在主循环之外。