2013-02-16 73 views
6

我正在嘗試使用基於來自用戶的輸入的if-test來重新啓動程序。如何根據用戶輸入重新啓動程序?

此代碼不能正常工作,但它是約我後:

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

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

我試圖做的是:

  • 如果你回答y - 程序重新啓動如果你回答n - 程序結束(該部分工作)
  • 如果你輸入了其他東西,它應該打印'無效輸入。請輸入y或n ...'或其他內容,並再次詢問您是否有新的輸入。

我真的接近帶有「while true」循環的解決方案,但無論按下哪個按鈕(n除外),程序都會重新啓動,或者不管按什麼按鈕(y除外)都會退出。有任何想法嗎?

回答

4

嘗試這種情況:

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 

while循環循環,直到所述輸入要麼是'y''n'內。如果輸入爲'y',則while循環再次啓動(關鍵字跳過剩餘的代碼並直接進入下一次迭代)。如果輸入是'n',則程序結束。

另請注意,將raw_input轉換爲str()是冗餘的,因爲raw_input已經返回一個字符串。

1

這裏有一個有趣的方式與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() 

最後,我想你需要2個while循環。您需要一個循環包圍提示答案的部分,以便在用戶輸入錯誤時再次提示。您需要一秒鐘的時間來檢查當前的答案是否爲'y'並繼續運行代碼,直到答案不是'y'

2

使用一個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]: 
+0

好的,好的。很公平。你不需要* 2'while while循環 - 但我仍然認爲它更清潔:) - 我真的很喜歡我的裝飾器解決方案,但是對於這樣的問題,這可能有點高級... – mgilson 2013-02-16 05:24:28

+0

@ mgilson - 也許。但裝飾者*當然是*非常整齊,+1。 – root 2013-02-16 05:26:40

0

我創建這個程序:

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() 

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

+2

這是很長時間以致無法簡明地解釋如何重新啓動程序。 – 2015-03-30 01:07:44

10

這條線將無條件重新從頭開始運行程序:

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

與目前爲止的其餘建議相比,它的優勢之一就是程序本身將被再次讀取。

例如,如果您正在其他窗口中修改其代碼,這會很有用。

+1

如果Python安裝在具有空格的路徑中,這不適用於Windows – Beefster 2017-02-17 23:14:18

+1

@Beefster這可以通過使用'subprocess.call(sys.executable +'「'+ os.path.realpath(__ file__)+' 「')' – 2017-12-12 21:05:38

+0

@EladAvron該解決方案的問題在於它創建了一個無休止的子流程鏈,最終導致os耗盡內存。我不確定當時會發生什麼。 – Beefster 2017-12-14 17:19:36

2

您只需通過用戶定義的功能即可完成此操作。代碼是這樣的:

def script() 
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() 

當然,你可以在這裏改變很多東西。據說,腳本將接受哪些作爲有效輸入的變量和函數名稱。您可以簡單地將整個程序嵌套到用戶定義的函數中(當然,您必須將所有內容都放在一個額外的縮進中),並在任何時候使用以下代碼行重新啓動:myfunctionname()。更多內容here.

+0

當然,讓我知道如果這失敗了,我會嘗試修復 – 2015-06-10 15:34:49

相關問題