programing

인쇄 호출을 차단하는 방법

starjava 2023. 7. 31. 20:59
반응형

인쇄 호출을 차단하는 방법

가 함수호중수있방있습까니법이는지할을 호출하는 수 있는 ?print?


나는 지금 작업 중인 게임에 모듈을 사용하고 있습니다.

다음을 생성했습니다.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()당신이 그것을 계속하기를 선택합니다.모든 인쇄를 비활성화하려면 파일 맨 위에서 차단을 시작합니다.

사용하다with

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

@Alexander Chzhen이 제안했듯이, 상황 관리자를 사용하는 것이 상태 변화 기능 쌍을 호출하는 것보다 안전할 것입니다.

그러나 컨텍스트 관리자는 이미 표준 라이브러리에 있으므로 다시 구현할 필요가 없습니다.리디렉션할 수 있습니다.stdout는 (으)로 표시됩니다.print용도) 및 함께 사용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()

위해서Jupyter Notebooks당신은 아마도 그것을 교체해야 할 것입니다.func_wrapper코드:

from IPython.utils.io import capture_output

def func_wrapper(*args, **kwargs):
    with capture_output():
        value = func(*args, **kwargs)
    return value

주피터 노트북 또는 콜라브를 사용하는 경우 다음을 사용합니다.

from IPython.utils import io

with io.capture_output() as captured:
    print("I will not be printed.")

간단한 리디렉션을 수행할 수 있습니다. 이것은 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으로 호출하거나 input()을 사용하는 경우입니다.

해결책을 stderr에서 수 없음)을 저같문를고는스었다른, 않니찾에다리습했지출션고프렉을에 (stdout로디발그서생하는지서르겠습니생히하다는지확모정발이팸은의램겪제을력책결해der스r에▁i▁butd▁(▁redirect▁the▁solutioni▁st▁program지▁had▁and,▁to는der▁i다▁the니르겠습히▁to확지저는d▁st▁another/dev/null

사실, 오픈 소스이지만, 저는 그것에 뛰어들 만큼 열정적이지 않았습니다.pygame소스(및 빌드 프로세스)를 사용하여 어떻게든 디버그 스팸을 중지할 수 있습니다.

편집:

모듈에 다음과 같은 호출이 있습니다.printf실제 값을 Python으로 반환하는 모든 함수에서:

printf("SDL_JoystickGetButton value:%d:\n", value);

유감스럽게도 당신은 이것들에 대해 논평하고 전체를 다시 컴파일해야 할 것입니다. 제공된 마제된것것일공아일 것입니다.setup.py생각보다 쉽게 할 수 있을 겁니다당신도 해볼 수 있어요...

완전히 다른 접근 방식으로 명령줄을 리디렉션할 수 있습니다.Windows(윈도우)에서는 일괄 스크립트를 의미합니다.리눅스에서는 bash.

/full/path/to/my/game/game.py > /dev/null
C:\Full\Path\To\My\Game.exe > nul

여러 프로세스를 처리하는 경우가 아니라면 이 방법이 효과적일 것입니다.Windows 사용자의 경우 이 바로 가기를 만들 수 있습니다(시작 메뉴/바탕 화면).

아니요, 특히 PyGame의 대부분이 C로 작성되었다는 것은 없습니다.

하지만 이 기능이 프린트를 호출하면 파이게임 버그이고, 당신은 그냥 보고해야 합니다.

을 가내인모은듈에 인쇄했습니다.stderr 그 의 해결책은 다음과

sys.stdout = open(os.devnull, 'w')
"stop a function from calling print"
# import builtins
# import __builtin__ # python2, not test
printenabled = False
def decorator(func):
    def new_func(*args,**kwargs):
        if printenabled:
            func("print:",*args,**kwargs)
    return new_func
print = decorator(print) # current file
# builtins.print = decorator(builtins.print)  # all files
# __builtin__.print = decorator(__builtin__.print) # python2

import sys
import xxxxx
def main():
    global printenabled
    printenabled = True
    print("1 True");
    printenabled = False
    print("2 False");
    printenabled = True
    print("3 True");
    printenabled = False
    print("4 False");
if __name__ == '__main__':
    sys.exit(main())

#output
print: 1 True
print: 3 True

https://stackoverflow.com/a/27622201

print.print() 합니다.기본적으로 다음과 같습니다.sys.stdout에 " " " " null " null " "로 쓸 수.open(os.devnull, 'w')

import os, sys

mode = 'debug' #'prod'

if mode == 'debug':
    fileobj = sys.stdout
else:
    fileobj = open(os.devnull,'w')

print('Hello Stackoverflow', file = fileobj)

@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

알렉산더의 답변 아래에 나의 해결책을 코멘트로 추가할 수 있기를 바라지만, 그렇게 하기에는 (50개의) 평판이 부족합니다.

변수를 사용하여 인쇄를 활성화/비활성화하려면 인쇄 대신 보조 기능을 호출할 수 있습니다(이름은 편의상).

def printe(*what_to_print):
if prints_enable:
    string = ""
    for items in what_to_print:
        string += str(items) + " "
    print(string)

먼저 인쇄를 활성화하고 다음으로 출력을 인쇄하는 새로운 인쇄 기능을 정의합니다.그런 다음 인쇄를 다시 비활성화합니다.

def Print (*output):
   enablePrint()
   print (output)
   disablePrint()

위의 "안전한" 활성화/비활성화 기능 쌍 중 하나로

언급URL : https://stackoverflow.com/questions/8391411/how-to-block-calls-to-print

반응형