함수 호출을 중지하는 방법이 print
있습니까?
pygame.joystick
작업중인 게임에 모듈을 사용 하고 있습니다.
pygame.joystick.Joystick
개체를 만들고 게임의 실제 루프에서 해당 멤버 함수 get_button
를 호출하여 사용자 입력을 확인합니다. 이 함수는 필요한 모든 작업을 수행하지만 문제 print
는를 호출 하여 게임 속도가 상당히 느려진다는 것입니다.
이 전화를 차단할 수 있습니까 print
?
함수 호출을 중지하는 방법이 print
있습니까?
pygame.joystick
작업중인 게임에 모듈을 사용 하고 있습니다.
pygame.joystick.Joystick
개체를 만들고 게임의 실제 루프에서 해당 멤버 함수 get_button
를 호출하여 사용자 입력을 확인합니다. 이 함수는 필요한 모든 작업을 수행하지만 문제 print
는를 호출 하여 게임 속도가 상당히 느려진다는 것입니다.
이 전화를 차단할 수 있습니까 print
?
답변:
Python을 사용하면 모든 파일 객체로 표준 출력 (stdout)을 덮어 쓸 수 있습니다. 이것은 크로스 플랫폼에서 작동하고 null 장치에 기록되어야합니다.
import sys, os
# Disable
def blockPrint():
sys.stdout = open(os.devnull, 'w')
# Restore
def enablePrint():
sys.stdout = sys.__stdout__
print 'This will print'
blockPrint()
print "This won't"
enablePrint()
print "This will too"
한 함수가 인쇄되는 것을 원하지 않으면 그 blockPrint()
전에 호출 enablePrint()
하고 계속하려면 호출 하십시오 . 모든 인쇄 를 비활성화 하려면 파일 상단에서 차단을 시작하십시오.
@FakeRainBrigand 솔루션을 기반으로 더 안전한 솔루션을 제안합니다.
import os, sys
class HiddenPrints:
def __enter__(self):
self._original_stdout = sys.stdout
sys.stdout = open(os.devnull, 'w')
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stdout.close()
sys.stdout = self._original_stdout
그런 다음 다음과 같이 사용할 수 있습니다.
with HiddenPrints():
print("This will not be printed")
print("This will be printed as before")
예외를 처리 할 때 특히 중요한 stdout을 다시 활성화하는 것을 잊을 수 없기 때문에 훨씬 안전합니다.
with
다음 예제에서는 이전 답변에서 제안 된 인쇄 활성화 / 비활성화 기능을 사용합니다.
예외를 발생시킬 수있는 코드가 있다고 상상해보십시오. finally
어떤 경우에도 인화를 가능하게 하려면 문 을 사용해야했습니다 .
try:
disable_prints()
something_throwing()
enable_prints() # This will not help in case of exception
except ValueError as err:
handle_error(err)
finally:
enable_prints() # That's where it needs to go.
finally
절 을 잊은 경우 print
호출은 더 이상 아무것도 인쇄하지 않습니다.
with
인쇄가 다시 활성화되도록 하는 문 을 사용하는 것이 더 안전합니다 .
참고 : sys.stdout = None
누군가 다음과 같은 메서드를 호출 할 수 있으므로를 사용하는 것은 안전하지 않습니다.sys.stdout.write()
ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='w' encoding='UTF-8'>
이 코드를 사용하는 경우 ( 'W', os.devnull) 대신 개방의 sys.stdout = 없음을 설정하지하여 해결,
sys.stdout.close()
이탈 방법을 추가 했습니다. 이것은 도움이 될 것입니다. 참고 sys.stdout = None
누군가가 같은 표준 출력의 메소드를 호출 할 수 있기 때문에, 오류가 발생할 수 있습니다 sys.stdout.write()
.
@Alexander Chzhen이 제안했듯이 컨텍스트 관리자를 사용하는 것이 한 쌍의 상태 변경 함수를 호출하는 것보다 안전합니다.
그러나 컨텍스트 관리자를 다시 구현할 필요는 없습니다. 이미 표준 라이브러리에 있습니다. 당신은 리디렉션 할 수 있습니다 stdout
(즉, 파일 객체 print
와 용도) contextlib.redirect_stdout
, 또한 stderr
으로 contextlib.redirect_stderr
.
import os
import contextlib
with open(os.devnull, "w") as f, contextlib.redirect_stdout(f):
print("This won't be printed.")
특정 기능에 의한 인쇄 호출을 차단하려면 데코레이터를 사용하는 더 깔끔한 솔루션이 있습니다. 다음 데코레이터를 정의하십시오.
# decorater used to block function printing to the console
def blockPrinting(func):
def func_wrapper(*args, **kwargs):
# block all printing to the console
sys.stdout = open(os.devnull, 'w')
# call the method in question
value = func(*args, **kwargs)
# enable all printing to the console
sys.stdout = sys.__stdout__
# pass the return value of the method back
return value
return func_wrapper
그런 다음 @blockPrinting
기능 앞에 배치 하십시오. 예를 들면 :
# This will print
def helloWorld():
print("Hello World!")
helloWorld()
# This will not print
@blockPrinting
def helloWorld2():
print("Hello World!")
helloWorld2()
아니요, 특히 대부분의 PyGame이 C로 작성되었습니다.
그러나이 함수가 print를 호출하면 PyGame 버그이므로보고 만하면됩니다.
나는 똑같은 문제가 있었고 다른 해결책으로 오지 않았지만 프로그램의 출력을 (stdout 또는 stderr에서 스팸이 발생하는지 정확히 알지 못함) /dev/null
너바나 로 리디렉션했습니다 .
사실, 그것은 오픈 소스이지만, 나는 pygame
소스와 빌드 프로세스 에 뛰어 들어서 어떻게 든 디버그 스팸을 막을 만큼 열정적이지 않았습니다 .
편집하다 :
pygame.joystick
모듈 에 대한 호출이 printf
파이썬에 실제 값을 반환하는 모든 기능의를 :
printf("SDL_JoystickGetButton value:%d:\n", value);
불행히도 이것들을 주석 처리하고 전체를 다시 컴파일해야합니다. 아마도 제공된 setup.py
것이 내가 생각했던 것보다 쉽게 만들 것입니다. 시도해 볼 수 있습니다 ...
@Alexander Chzhen 솔루션을 기반으로 인쇄를 억제할지 여부를 옵션으로 기능에 적용하는 방법을 여기에 제시합니다.
import os, sys
class SuppressPrints:
#different from Alexander`s answer
def __init__(self, suppress=True):
self.suppress = suppress
def __enter__(self):
if self.suppress:
self._original_stdout = sys.stdout
sys.stdout = open(os.devnull, 'w')
def __exit__(self, exc_type, exc_val, exc_tb):
if self.suppress:
sys.stdout.close()
sys.stdout = self._original_stdout
#implementation
def foo(suppress=True):
with SuppressPrints(suppress):
print("It will be printed, or not")
foo(True) #it will not be printed
foo(False) #it will be printed
Alexander의 답변 아래에 내 솔루션을 주석으로 추가 할 수 있기를 바랍니다.하지만 그렇게 할만한 평판이 충분하지 않습니다.
간단한 리디렉션을 수행 할 수 있습니다. 이것은 stdout을 엉망으로 만드는 것보다 훨씬 안전 해 보이며 추가 라이브러리를 가져 오지 않습니다.
enable_print = print
disable_print = lambda *x, **y: None
print = disable_print
function_that_has_print_in_it(1) # nothing is printed
print = enable_print
function_that_has_print_in_it(2) # printing works again!
참고 : 이것은 print () 함수를 비활성화하는 데만 작동하며 출력을 생성하는 다른 항목을 호출하는 경우 모든 출력을 비활성화하지 않습니다. 예를 들어 자체 출력을 생성하는 C 라이브러리를 stdout으로 호출하거나 intput ()을 사용하는 경우입니다.