2010-01-24 37 views
19

Tôi đang sử dụng mô-đun cần điều khiển của Pygame/SDL để nhận dữ liệu đầu vào từ một gamepad. Mỗi lần tôi gọi phương thức get_hat() của nó, nó in ra bàn điều khiển. Đây là vấn đề kể từ khi tôi sử dụng giao diện điều khiển để giúp tôi gỡ lỗi và bây giờ nó bị ngập với SDL_JoystickGetHat value:0: 60 lần mỗi giây. Có cách nào tôi có thể vô hiệu hóa điều này? Hoặc là thông qua một tùy chọn trong Pygame/SDL hoặc tắt giao diện điều khiển đầu ra trong khi chức năng gọi? Tôi thấy không có đề cập đến điều này trong tài liệu Pygame.Làm thế nào để ngăn chặn đầu ra console trong Python?

chỉnh sửa: Điều này hóa ra là do gỡ lỗi được bật khi thư viện SDL được biên dịch.

+0

Bây giờ tôi tò mò những gì nền tảng mà bạn đang sử dụng (Linux distro?), Và những gì gói bạn đang sử dụng? Hay bạn đã tự biên dịch nó? – Keith

+0

Đây là một thời gian dài trước đây, nhưng tôi đã sử dụng Windows, Python 2.6 và Pygame 1.9 (bao gồm SDL). Tôi đã đi với trình cài đặt Windows của họ và tất cả mọi thứ đã được biên soạn. – tankadillo

Trả lời

3

Dưới đây là các khối có liên quan của mã từ joystick.c (thông qua SVN tại http://svn.seul.org/viewcvs/viewvc.cgi/trunk/src/joystick.c?view=markup&revision=2652&root=PyGame)

value = SDL_JoystickGetHat (joy, _index); 
#ifdef DEBUG 
    printf("SDL_JoystickGetHat value:%d:\n", value); 
#endif 
    if (value & SDL_HAT_UP) { 

Trông giống như một vấn đề với khi gỡ lỗi bật.

+0

Làm cách nào để vô hiệu hóa gỡ lỗi SDL mặc dù Python? Google cho tôi biết biến môi trường là 'SDL_DEBUG' nhưng chèn' os.environ ['SDL_DEBUG'] = '0'' dường như không có hiệu lực. – tankadillo

+4

@jackson đó là tùy chọn gỡ lỗi thời gian biên dịch cho SDL. Tin nhắn đang in vì khi thư viện SDL của bạn được biên dịch, biểu tượng DEBUG đã được xác định. –

+0

Ah, được rồi. Cảm ơn đã giúp đỡ! – tankadillo

10

Bạn có thể giải quyết vấn đề này bằng cách ấn định lỗi/lỗi tiêu chuẩn (Tôi không biết nó sẽ đi tới thiết bị null). Trong Python, tiêu chuẩn ra khỏi file/lỗi là sys.stdout/sys.stderr, và các thiết bị null là os.devnull, vì vậy bạn làm

sys.stdout = os.devnull 
sys.stderr = os.devnull 

này nên vô hiệu hóa các thông báo lỗi hoàn toàn. Thật không may, điều này cũng sẽ vô hiệu hóa tất cả các đầu ra console. Để làm được việc này, vô hiệu hóa đầu ra ngay trước khi gọi get_hat() phương pháp, và sau đó khôi phục nó bằng cách làm

sys.stdout = sys.__stdout__ 
sys.stderr = sys.__stderr__ 

mà khôi phục tiêu chuẩn ra ngoài và báo lỗi với giá trị ban đầu của họ.

+0

Tôi đã không nhận thức được kỹ thuật này trước đây. Nó dường như là những gì tôi muốn, nhưng khi tôi thử sử dụng nó, hàm get_hat() tiếp tục in ra bàn điều khiển. Đây có phải là vấn đề với SDL không? – tankadillo

+1

Sử dụng các trình giữ chỗ cho sys.stdout và sys.stderr ban đầu để sử dụng khi khôi phục stdout sẽ mở rộng giải pháp này để làm việc trong các tình huống mà một stdout 'không chuẩn' đã có sẵn và cần được giữ lại sau khi triệt tiêu. ví dụ để sử dụng trong giao diện điều khiển python QGIS. –

+1

bit đầu tiên hoạt động, tuy nhiên ngay cả với bit 'khôi phục' mã tôi vẫn không nhận được bất kỳ đầu ra console nào sau nó? Tôi đang ở trên Ubuntu 14.04 với 3.4.3 – ashgetstazered

1

Tôi sử dụng pythonw.exe (trên Windows) thay vì python.exe. Trong các hệ điều hành khác, bạn cũng có thể chuyển hướng đầu ra tới/dev/nul. Và để vẫn thấy đầu ra gỡ lỗi của tôi, tôi đang sử dụng mô đun ghi nhật ký.

1

Demolishun đề cập đến trong một answer cho câu hỏi trùng lặp đã đóng, có một số thread nói về vấn đề này. Chủ đề là từ tháng 8 năm 2009 và một trong các nhà phát triển cho biết the debug code was left in on accident. Tôi đã cài đặt Pygame 1.9.1 từ pip và đầu ra gỡ lỗi vẫn còn hiện diện.

Để giải quyết vấn đề này ngay bây giờ, tôi đã tải xuống nguồn từ pygame.org, xóa các câu lệnh in khỏi src/joystick.c và biên dịch mã.

Tôi đang sử dụng OS X 10.7.5 cho giá trị của nó.

17

Chỉ cần cho đầy đủ, đây là một giải pháp tốt đẹp từ Dave Smith's blog:

from contextlib import contextmanager 
import sys, os 

@contextmanager 
def suppress_stdout(): 
    with open(os.devnull, "w") as devnull: 
     old_stdout = sys.stdout 
     sys.stdout = devnull 
     try: 
      yield 
     finally: 
      sys.stdout = old_stdout 

Với điều này, bạn có thể sử dụng quản lý bối cảnh bất cứ nơi nào bạn muốn ngăn chặn đầu ra:

print("Now you see it") 
with suppress_stdout(): 
    print("Now you don't") 
0

Nếu bạn đang ở trên một Debian hoặc máy Ubuntu bạn chỉ có thể biên dịch lại pygame mà không cần thông báo.

cd /tmp 
sudo apt-get build-dep pygame 
apt-get source pygame 
vim pygame-1.9.1release+dfsg/src/joystick.c 
# search for the printf("SDL.. messages and put a // in front 
apt-get source --compile pygame 
sudo dpkg -i python-pygame_1.9.1release+dfsg-9ubuntu1_amd64.deb 

Greetings Max

2

Để hoàn thành câu trả lời charles của, có hai cán bộ quản lý bối cảnh xây dựng trong để trăn, redirect_stdoutredirect_stderr mà bạn có thể sử dụng để chuyển hướng và hoặc ngăn chặn một đầu ra lệnh cho một tập tin hoặc StringIO biến .

import contextlib 

with contextlib.redirect_stdout(None): 
    do_thing() 

Đối với một giải thích đầy đủ hơn đọc the docs

+1

Cảm ơn mẹo. Bạn cũng có thể thêm câu lệnh in làm tham số trong redirect_stdout(). 'với redirect_stdout (in ('Làm việc!')): do_thing()' – myidealab

Các vấn đề liên quan