Python 如何根据用户输入重新启动程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14907067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:49:01  来源:igfitidea点击:

How do I restart a program based on user input?

python

提问by MagnusIngemann

I'm trying to restart a program using an if-test based on the input from the user.

我正在尝试使用基于用户输入的 if-test 重新启动程序。

This code doesn't work, but it's approximately what I'm after:

这段代码不起作用,但它大约是我所追求的:

answer = str(raw_input('Run again? (y/n): '))

if answer == 'n':
   print 'Goodbye'
   break
elif answer == 'y':
   #restart_program???
else:
   print 'Invalid input.'

What I'm trying to do is:

我想要做的是:

  • if you answer y - the program restarts from the top
  • if you answer n - the program ends (that part works)
  • if you enter anything else, it should print 'invalid input. please enter y or n...' or something, and ask you again for new input.
  • 如果你回答 y - 程序从顶部重新启动
  • 如果您回答 n - 程序结束(该部分有效)
  • 如果您输入其他任何内容,它应该打印“无效输入”。请输入 y 或 n...' 或其他内容,然后再次要求您输入新的内容。

I got really close to a solution with a "while true" loop, but the program either just restarts no matter what you press (except n), or it quits no matter what you press (except y). Any ideas?

我非常接近带有“while true”循环的解决方案,但是无论您按什么,程序都会重新启动(n 除外),或者无论您按什么都退出(y 除外)。有任何想法吗?

采纳答案by Volatility

Try this:

尝试这个:

while True:
    # main program
    while True:
        answer = raw_input('Run again? (y/n): ')
        if answer in ('y', 'n'):
            break
        print 'Invalid input.'
    if answer == 'y':
        continue
    else:
        print 'Goodbye'
        break

The inner while loop loops until the input is either 'y'or 'n'. If the input is 'y', the while loop starts again (continuekeyword skips the remaining code and goes straight to the next iteration). If the input is 'n', the program ends.

内部 while 循环循环直到输入是'y'or 'n'。如果输入是'y',while 循环再次开始(continue关键字跳过剩余的代码并直接进入下一次迭代)。如果输入为'n',则程序结束。

Also note that converting raw_inputto a str()is redundant since raw_inputalready returns a string.

另请注意,转换raw_input为 astr()是多余的,因为raw_input已经返回了一个字符串。

回答by mgilson

Here's a fun way to do it with a decorator:

这是使用装饰器的一种有趣方式:

def restartable(func):
    def wrapper(*args,**kwargs):
        answer = 'y'
        while answer == 'y':
            func(*args,**kwargs)
            while True:
                answer = raw_input('Restart?  y/n:')
                if answer in ('y','n'):
                    break
                else:
                    print "invalid answer"
    return wrapper

@restartable
def main():
    print "foo"

main()

Ultimately, I think you need 2 while loops. You need one loop bracketing the portion which prompts for the answer so that you can prompt again if the user gives bad input. You need a second which will check that the current answer is 'y'and keep running the code until the answer isn't 'y'.

最终,我认为您需要 2 个 while 循环。您需要一个循环将提示输入答案的部分括起来,以便在用户输入错误时再次提示。您需要一秒钟来检查当前答案是否为'y'并继续运行代码,直到答案不是'y'

回答by root

Using one while loop:

使用一个 while 循环:

In [1]: start = 1
   ...: 
   ...: while True:
   ...:     if start != 1:        
   ...:         do_run = raw_input('Restart?  y/n:')
   ...:         if do_run == 'y':
   ...:             pass
   ...:         elif do_run == 'n':
   ...:             break
   ...:         else: 
   ...:             print 'Invalid input'
   ...:             continue
   ...: 
   ...:     print 'Doing stuff!!!'
   ...: 
   ...:     if start == 1:
   ...:         start = 0
   ...:         
Doing stuff!!!

Restart?  y/n:y
Doing stuff!!!

Restart?  y/n:f
Invalid input

Restart?  y/n:n

In [2]:

回答by root

I create this program:

我创建了这个程序:

import pygame, sys, time, random, easygui

skier_images = ["skier_down.png", "skier_right1.png",
                "skier_right2.png", "skier_left2.png",
                "skier_left1.png"]

class SkierClass(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("skier_down.png")
        self.rect = self.image.get_rect()
        self.rect.center = [320, 100]
        self.angle = 0

    def turn(self, direction):
        self.angle = self.angle + direction
        if self.angle < -2:  self.angle = -2
        if self.angle >  2:  self.angle =  2
        center = self.rect.center
        self.image = pygame.image.load(skier_images[self.angle])
        self.rect = self.image.get_rect()
        self.rect.center = center
        speed = [self.angle, 6 - abs(self.angle) * 2]
        return speed

    def move(self,speed):
        self.rect.centerx = self.rect.centerx + speed[0]
        if self.rect.centerx < 20:  self.rect.centerx = 20
        if self.rect.centerx > 620: self.rect.centerx = 620

class ObstacleClass(pygame.sprite.Sprite):
    def __init__(self,image_file, location, type):
        pygame.sprite.Sprite.__init__(self)
        self.image_file = image_file
        self.image = pygame.image.load(image_file)
        self.location = location
        self.rect = self.image.get_rect()
        self.rect.center = location
        self.type = type
        self.passed = False

    def scroll(self, t_ptr):
        self.rect.centery = self.location[1] - t_ptr

def create_map(start, end):
    obstacles = pygame.sprite.Group()
    gates = pygame.sprite.Group()
    locations = []
    for i in range(10):
        row = random.randint(start, end)
        col = random.randint(0, 9)
        location = [col * 64 + 20, row * 64 + 20]
        if not (location in locations) :
            locations.append(location)
            type = random.choice(["tree", "flag"])
            if type == "tree": img = "skier_tree.png"
            elif type == "flag": img = "skier_flag.png"
            obstacle = ObstacleClass(img, location, type)
            obstacles.add(obstacle)
    return obstacles

def animate():
    screen.fill([255,255,255])
    pygame.display.update(obstacles.draw(screen))
    screen.blit(skier.image, skier.rect)
    screen.blit(score_text, [10,10])
    pygame.display.flip()

def updateObstacleGroup(map0, map1):
    obstacles = pygame.sprite.Group()
    for ob in map0:  obstacles.add(ob)
    for ob in map1:  obstacles.add(ob)
    return obstacles

pygame.init()
screen = pygame.display.set_mode([640,640])
clock = pygame.time.Clock()
skier = SkierClass()
speed = [0, 6]
map_position = 0
points = 0
map0 = create_map(20, 29)
map1 = create_map(10, 19)
activeMap = 0
obstacles = updateObstacleGroup(map0, map1)
font = pygame.font.Font(None, 50)

a = True

while a:
    clock.tick(30)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                speed = skier.turn(-1)
            elif event.key == pygame.K_RIGHT:
                speed = skier.turn(1)
    skier.move(speed)
    map_position += speed[1]

    if map_position >= 640 and activeMap == 0:
        activeMap = 1
        map0 = create_map(20, 29)
        obstacles = updateObstacleGroup(map0, map1)
    if map_position >=1280 and activeMap == 1:
        activeMap = 0
        for ob in map0:
            ob.location[1] = ob.location[1] - 1280
        map_position = map_position - 1280
        map1 = create_map(10, 19)
        obstacles = updateObstacleGroup(map0, map1)
    for obstacle in obstacles:
        obstacle.scroll(map_position)

    hit = pygame.sprite.spritecollide(skier, obstacles, False)
    if hit:
        if hit[0].type == "tree" and not hit[0].passed:
            skier.image = pygame.image.load("skier_crash.png")
            easygui.msgbox(msg="OOPS!!!")
            choice = easygui.buttonbox("Do you want to play again?", "Play", ("Yes", "No"))
            if choice == "Yes":
                skier = SkierClass()
                speed = [0, 6]
                map_position = 0
                points = 0
                map0 = create_map(20, 29)
                map1 = create_map(10, 19)
                activeMap = 0
                obstacles = updateObstacleGroup(map0, map1)
            elif choice == "No":
                a = False
                quit()
        elif hit[0].type == "flag" and not hit[0].passed:
            points += 10
            obstacles.remove(hit[0])

    score_text = font.render("Score: " + str(points), 1, (0, 0, 0))
    animate()

Link: https://docs.google.com/document/d/1U8JhesA6zFE5cG1Ia3OsTL6dseq0Vwv_vuIr3kqJm4c/edit

链接:https: //docs.google.com/document/d/1U8JhesA6zFE5cG1Ia3OsTL6dseq0Vwv_vuIr3kqJm4c/edit

回答by jlliagre

This line will unconditionally restart the running program from scratch:

这一行将无条件地重新启动正在运行的程序:

os.execl(sys.executable, sys.executable, *sys.argv)

One of its advantage compared to the remaining suggestions so far is that the program itself will be read again.

与迄今为止的其余建议相比,它的优势之一是程序本身将被再次读取。

This can be useful if, for example, you are modifying its code in another window.

例如,如果您正在另一个窗口中修改其代码,这会很有用。

回答by It's Willem

You can do this simply with a function. For example:

你可以简单地用一个函数来做到这一点。例如:

def script():
    # program code here...
    restart = raw_input("Would you like to restart this program?")
    if restart == "yes" or restart == "y":
        script()
    if restart == "n" or restart == "no":
        print "Script terminating. Goodbye."
script()

Of course you can change a lot of things here. What is said, what the script will accept as a valid input, the variable and function names. You can simply nest the entire program in a user-defined function (Of course you must give everything inside an extra indent) and have it restart at anytime using this line of code: myfunctionname(). More on this here.

当然,您可以在这里更改很多内容。说什么,脚本将接受什么作为有效输入,变量和函数名称。你可以简单地窝在一个用户定义的函数整个程序(当然你必须给一切额外的缩进内),并把它在任何时候使用这行代码重新启动:myfunctionname()。更多关于这里。