질문자 :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
MarcHimport 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'가 포함됩니다.
slushyPython 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")
aaguirrePython 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 메서드를 사용하세요.
Rebsstdout에도 동일하게 적용됩니다.
print 'spam' sys.stdout.write('spam\n')
다른 답변에서 언급했듯이 print 는 종종 더 편리한 예쁜 인터페이스(예: 디버그 정보 인쇄용)를 제공하는 반면 쓰기 는 더 빠르고 특정 방식으로 정확하게 출력을 형식화해야 할 때 더 편리할 수도 있습니다. 유지 관리 가능성도 고려할 것입니다.
나중에 stdout/stderr과 일반 파일 간에 전환하기로 결정할 수 있습니다.
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