etc./StackOverFlow

Python에서 stderr로 인쇄하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2022. 2. 17. 12:25
반응형

질문자 :wim


stderr에 쓰는 방법에는 여러 가지가 있습니다.

 # Note: this first one does not work in Python 3 print >> sys.stderr, "spam" sys.stderr.write("spam\n") os.write(2, b"spam\n") from __future__ import print_function print("spam", file=sys.stderr)

그것은 Python #13 † 의 zen 과 모순되는 것 같으므로 여기서 차이점은 무엇이며 어떤 방식으로든 장단점이 있습니까? 어떤 방법을 사용해야 합니까?

이를 수행하는 확실한 방법이 하나 있어야 하며, 가급적이면 하나만 있어야 합니다.



나는 이것이 유일하게 짧고 유연하며 휴대 가능하고 읽기 쉽다는 것을 알았습니다.

 from __future__ import print_function import sys def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs)

eprint 함수 print 함수와 같은 방식으로 사용할 수 있습니다.

 >>> print("Test") Test >>> eprint("Test") Test >>> eprint("foo", "bar", "baz", sep="---") foo---bar---baz

MarcH

import sys sys.stderr.write()

내 선택은 더 읽기 쉽고 정확히 무엇을 하려는지 말하고 버전 간에 이식 가능합니다.

편집: '파이썬'이 되는 것은 가독성과 성능에 대한 세 번째 생각입니다... 이 두 가지를 염두에 두고 파이썬을 사용하면 코드의 80%가 파이썬이 됩니다. 목록 이해는 자주 사용되지 않는 '큰 것'입니다(가독성).


Mike Ramirez

파이썬 2:

 print >> sys.stderr, "fatal error"

파이썬 3:

 print("fatal error", file=sys.stderr)

긴 답변

print >> sys.stderr 은 Python3에서 사라졌습니다. http://docs.python.org/3.0/whatsnew/3.0.html 말한다 :

이전: print >> sys.stderr, "fatal error"
신규: print("fatal error", file=sys.stderr)

우리 중 많은 사람들에게 목적지를 명령의 끝으로 격하시키는 것은 다소 부자연스럽게 느껴집니다. 대안

 sys.stderr.write("fatal error\n")

더 객체 지향적으로 보이고 일반에서 특정으로 우아하게 이동합니다. 그러나 write print 1:1 로 대체하지 않습니다.


Joachim W

아직 아무도 logging 언급하지 않았지만 로깅은 특히 오류 메시지를 전달하기 위해 만들어졌습니다. 기본 구성은 stderr에 쓰는 스트림 핸들러를 설정합니다.

이 스크립트:

 # foo.py import logging logging.basicConfig(format='%(message)s') log = logging.getLogger(__name__) log.warning('I print to stderr by default') print('hello world')

명령줄에서 실행하면 다음과 같은 결과가 나타납니다.

 $ python3 foo.py > bar.txt I print to stderr by default

그리고 bar.txt 에는 stdout에 인쇄된 'hello world'가 포함됩니다.


slushy

Python 2의 경우 내 선택은 다음과 같습니다. print >> sys.stderr, 'spam' 문자열로 변환하지 않고 목록/사전 등을 간단히 인쇄할 수 있기 때문입니다. print >> sys.stderr, {'spam': 'spam'} 대신: sys.stderr.write(str({'spam': 'spam'}))


Frankovskyi Bogdan

귀하의 첫 번째 접근 방식은 다음과 같습니다.

 print >> sys.stderr, 'spam'

"그것을 할 수 있는 하나의 ... 분명한 방법"은 다른 하나는 규칙 #1을 충족하지 않습니다("아름다운 것이 못생긴 것보다 낫습니다.").

-- 2020년 편집 --

위의 내용은 2011년 Python 2.7에 대한 답변이었습니다. 이제 Python 3이 표준이므로 "정답"은 다음과 같습니다.

 print("spam", file=sys.stderr)

Carl F.

Python 3을 사용하여 다음을 수행했습니다.

 from sys import stderr def print_err(*args, **kwargs): print(*args, file=stderr, **kwargs)

이제 캐리지 리턴을 피하기 위해 키워드 인수를 추가할 수 있습니다.

 print_err("Error: end of the file reached. The word ", end='') print_err(word, "was not found")

aaguirre

Python 3에서는 print()를 사용할 수 있습니다.

 print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

거의 즉시 사용 가능:

 import sys print("Hello, world!", file=sys.stderr)

또는:

 from sys import stderr print("Hello, world!", file=stderr)

sys.stderr 외에 아무것도 포함할 필요가 없습니다.


Florian Castellane

이것은 표준 인쇄 기능을 모방하지만 stderr에 출력됩니다.

 def print_err(*args): sys.stderr.write(' '.join(map(str,args)) + '\n')

Brian W.

편집 나중에 보면 sys.stderr을 변경하고 업데이트된 동작을 보지 못하는 잠재적인 혼란으로 인해 이 답변이 다른 사람들이 지적한 것처럼 단순한 기능을 사용하는 것만큼 좋지 않다고 생각합니다.

부분을 사용하면 한 줄의 코드만 절약됩니다. 잠재적인 혼란은 한 줄의 코드를 저장할 가치가 없습니다.

원래의

좀 더 쉽게 하기 위해 함수를 래핑하는 데 큰 도움이 되는 'partial'을 사용하는 버전이 있습니다.

 from __future__ import print_function import sys from functools import partial error = partial(print, file=sys.stderr)

그런 다음 사용하십시오.

 error('An error occured!')

다음을 수행하여 표준 출력이 아닌 표준 오류로 인쇄되고 있는지 확인할 수 있습니다( http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and .html ):

 # over-ride stderr to prove that this function works. class NullDevice(): def write(self, s): pass sys.stderr = NullDevice() # we must import print error AFTER we've removed the null device because # it has been assigned and will not be re-evaluated. # assume error function is in print_error.py from print_error import error # no message should be printed error("You won't see this error!")

이것의 단점은 생성 시 래핑된 함수에 sys.stderr 값을 부분적으로 할당한다는 것입니다. 즉, 나중에 stderr을 리디렉션하면 이 기능에 영향을 미치지 않습니다. stderr을 리디렉션할 계획이라면 이 페이지에서 aaguirre가 언급한 **kwargs 메서드를 사용하세요.


Rebs

stdout에도 동일하게 적용됩니다.

 print 'spam' sys.stdout.write('spam\n')

다른 답변에서 언급했듯이 print 는 종종 더 편리한 예쁜 인터페이스(예: 디버그 정보 인쇄용)를 제공하는 반면 쓰기 는 더 빠르고 특정 방식으로 정확하게 출력을 형식화해야 할 때 더 편리할 수도 있습니다. 유지 관리 가능성도 고려할 것입니다.

  1. 나중에 stdout/stderr과 일반 파일 간에 전환하기로 결정할 수 있습니다.

  2. print() 구문이 Python 3에서 변경되었으므로 두 버전을 모두 지원해야 하는 경우 write() 가 더 나을 수 있습니다.


Seppo Enarvi

저는 파이썬 3.4.3에서 일하고 있습니다. 나는 내가 어떻게 여기에 왔는지 보여주는 약간의 타이핑을 잘라내고 있습니다.

 [18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 >>> import sys >>> print("testing", file=sys.stderr) testing >>> [18:19 jsilverman@JSILVERMAN-LT7 pexpect]$

효과가 있었나요? stderr을 파일로 리디렉션하고 어떤 일이 발생하는지 확인하십시오.

 [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 2> /tmp/test.txt >>> import sys >>> print("testing", file=sys.stderr) >>> [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ cat /tmp/test.txt Python 3.4.3 (default, May 5 2015, 17:58:45) [GCC 4.9.2] on cygwin Type "help", "copyright", "credits" or "license" for more information. testing [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$

글쎄, python이 제공하는 약간의 소개가 stderr에 slurped되었다는 사실을 제외하고(다른 곳으로 갈까요?), 작동합니다.


Jeff Silverman

치명적인 오류로 인해 프로그램을 종료하려면 다음을 사용하십시오.

 sys.exit("Your program caused a fatal error. ... description ...")

헤더에 import sys


feli_x

간단한 테스트를 수행하는 경우:

 import time import sys def run1(runs): x = 0 cur = time.time() while x < runs: x += 1 print >> sys.stderr, 'X' elapsed = (time.time()-cur) return elapsed def run2(runs): x = 0 cur = time.time() while x < runs: x += 1 sys.stderr.write('X\n') sys.stderr.flush() elapsed = (time.time()-cur) return elapsed def compare(runs): sum1, sum2 = 0, 0 x = 0 while x < runs: x += 1 sum1 += run1(runs) sum2 += run2(runs) return sum1, sum2 if __name__ == '__main__': s1, s2 = compare(1000) print "Using (print >> sys.stderr, 'X'): %s" %(s1) print "Using (sys.stderr.write('X'),sys.stderr.flush()):%s" %(s2) print "Ratio: %f" %(float(s1) / float(s2))

sys.stderr.write()가 일관되게 1.81 배 더 빠릅니다!


ThePracticalOne

질문에 대한 대답은 다음과 같습니다. 파이썬에서 stderr을 인쇄하는 다른 방법이 있지만 1.) 우리가 사용하는 파이썬 버전 2.) 우리가 원하는 정확한 출력에 따라 다릅니다.

print와 stderr의 쓰기 함수의 차이점: stderr : stderr(표준 오류)은 모든 UNIX/Linux 시스템에 내장된 파이프입니다. 프로그램이 충돌하고 디버깅 정보(Python의 역추적 같은)를 인쇄하면 stderr로 이동합니다. 파이프.

print : print는 입력 형식을 지정하는 래퍼이며(입력은 인수와 끝에 있는 줄 바꿈 사이의 공간임) 주어진 객체의 쓰기 기능을 호출합니다. 주어진 객체는 기본적으로 sys.stdout이지만 우리는 다음과 같이 할 수 있습니다. 파일을 전달합니다. 즉, 파일의 입력도 인쇄할 수 있습니다.

Python2: python2를 사용하는 경우

 >>> import sys >>> print "hi" hi >>> print("hi") hi >>> print >> sys.stderr.write("hi") hi

Python2 후행 쉼표는 Python3에서 매개변수가 되므로 인쇄 후 줄 바꿈을 피하기 위해 후행 쉼표를 사용하면 Python3에서 이것은 Python2에서 구문 오류인 print('Text to print', end=' ')처럼 보일 것입니다. .

http://python3porting.com/noconv.html

python3에서 위의 sceario를 동일하게 확인하면 :

 >>> import sys >>> print("hi") hi

Python 2.6에서는 인쇄를 함수로 만드는 향후 가져오기가 있습니다. 따라서 구문 오류 및 기타 차이점을 피하기 위해 from future import print_function과 함께 print()를 사용하는 모든 파일을 시작해야 합니다. 향후 가져오기는 Python 2.6 이상에서만 작동하므로 Python 2.5 이하에서는 두 가지 옵션이 있습니다. 더 복잡한 인쇄를 더 간단한 것으로 변환하거나 Python2 및 Python3 모두에서 작동하는 별도의 인쇄 기능을 사용할 수 있습니다.

 >>> from __future__ import print_function >>> >>> def printex(*args, **kwargs): ... print(*args, file=sys.stderr, **kwargs) ... >>> printex("hii") hii >>>

사례: sys.stderr.write() 또는 sys.stdout.write() ( stdout(표준 출력)는 모든 UNIX/Linux 시스템에 내장된 파이프입니다)는 인쇄를 대체할 수 없지만 그렇습니다. 어떤 경우에는 대안으로 사용할 수 있습니다. Print는 입력을 끝에 공백과 개행으로 감싸고 쓰기 기능을 사용하여 작성하는 래퍼입니다. 이것이 sys.stderr.write()가 더 빠른 이유입니다.

참고: Logging을 사용하여 추적하고 디버깅할 수도 있습니다.

 #test.py import logging logging.info('This is the existing protocol.') FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s" logging.basicConfig(format=FORMAT) d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} logging.warning("Protocol problem: %s", "connection reset", extra=d)

https://docs.python.org/2/library/logging.html#logger-objects


Vinay Kumar

출처 : http:www.stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python

반응형