2012-12-22 37 views
6

Tôi đã viết một chương trình nguyền rủa trong python. Nó chạy tốt. Tuy nhiên, khi tôi sử dụng nodelay(), chương trình sẽ thoát ngay lập tức sau khi bắt đầu trong thiết bị đầu cuối, không có gì được hiển thị (chỉ là một lời nhắc mới).nodelay() khiến chương trình nguyền rủa python thoát ra

EDIT

Mã này sẽ tái tạo các lỗi:

 
sc = curses.initscr() 

sc.nodelay(1) # But removing this line allows the program to run properly 

for angry in range(20): 
     sc.addstr(angry, 1, "hi") 

Đây là mã đầy đủ của tôi

 
import curses, time, sys, random 

def paint(x, y, i): 
     #... 
def string(s, y): 
     #... 

def feed(): 
     #... 

sc = curses.initscr() 
curses.start_color() 
curses.curs_set(0) 
sc.nodelay(1) ######################################### 

# vars + colors inited 

for angry in range(20): 
     try: 
       dir = chr(sc.getch()) 

       sc.clear() 

       feed() 

       #lots of ifs 

       body.append([x, y]) 
       body.pop(0) 

       for point in body: 
         paint(*point, i=2) 

       sc.move(height-1, 1) 
       sc.refresh() 
       time.sleep(wait) 

     except Exception as e: 
       print sys.exc_info()[0], e 

sc.getch() 
curses.beep() 

curses.endwin() 

Tại sao happenning này, và làm thế nào tôi có thể sử dụng nodelay() một cách an toàn?

+1

Hãy thử viết mã của bạn xuống mức tối thiểu cần thiết để tạo lại lỗi. Ví dụ bạn có thể thiết lập nodelay(), sau đó đi vào một vòng lặp vô hạn mà phá vỡ và thoát khi bạn getch() một khóa. Nếu lỗi đó biến mất trong trường hợp kiểm tra tối thiểu, hãy tìm hiểu xem điều gì đã thay đổi. Nếu điều đó không giúp đăng bài kiểm tra lỗi. – Philip

+0

@Philip suy nghĩ tốt, đã làm như vậy và đăng kết quả. – ACarter

Trả lời

5

Tôi đã viết lại bản trình diễn được rút gọn của bạn để có được chức năng cơ bản hoạt động. Nó có một getch(). Nếu bạn đang giữ phím Q khi getch() được gọi, chương trình kết thúc, nếu không vòng lặp sẽ tiếp diễn.

import curses, time 

def main(sc): 
    sc.nodelay(1) 

    for angry in range(20): 
     sc.addstr(angry, 1, "hi") 
     sc.refresh() 

     if sc.getch() == ord('q'): 
      break 

     time.sleep(1) 

if __name__=='__main__': 
    curses.wrapper(main) 

Thay đổi quan trọng nhất mà tôi đã thực hiện đang sử dụng curses.wrapper để có ngữ cảnh màn hình thay vì sử dụng curses.initscr(). Lợi ích là nếu điều đó nếu chương trình của bạn đạt được một ngoại lệ không bắt buộc (nhấn^C chẳng hạn), nó sẽ hoàn tác tất cả các thay đổi bạn đã thực hiện cho thiết bị đầu cuối như tắt con trỏ trước khi thoát. Nó giúp rất nhiều khi bạn đang gỡ lỗi.

Từ đây tôi khuyên bạn nên thêm các tính năng của chương trình của bạn trở lại theo các bước rất nhỏ. Lời nguyền là một nỗi đau để làm việc với và nếu bạn thực hiện nhiều thay đổi cùng một lúc thì thật khó để tìm ra cái nào gây ra sự cố. Chúc may mắn!

+1

Đã giải quyết. Thêm wrapper chính cho phép tôi thấy rằng tôi đã thoát khỏi một lỗi khi 'getch()' trả về không có gì (vì không có đầu vào nào), và đã được cố gắng đưa vào 'chr()', không thể xử lý không có gì. Cảm ơn bạn đã giúp đỡ, điều này sẽ thực sự hữu ích khi giải quyết các lỗi khác. – ACarter

0

Tôi thấy không có sự khác biệt khi chạy chương trình thử nghiệm nhỏ của bạn với hoặc mà không dòng sc.nodelay().

Cả hai trường hợp đều in bất cứ thứ gì trên màn hình ...

+0

Vấn đề là với tôi, với 'sc.nodelay()', một cửa sổ curses thậm chí không được mở ra, và do đó tôi không thể làm gì cả, vì không có gì để làm điều đó. – ACarter