stdout을 일종의 문자열 버퍼로 리디렉션할 수 있습니까?
나는 파이썬의 것을 사용하고 있습니다.ftplib
클라이언트를출력을 "" "FTP 클라트를패쓰일기다문작"로 인쇄합니다.stdout
리디렉션하려는 경우stdout
내가 출력을 읽을 수 있는 객체로.
알고있어요stdout
다음을 사용하여 일반 파일로 리디렉션할 수 있습니다.
stdout = open("file", "a")
하지만 저는 로컬 드라이브를 사용하지 않는 방법을 선호합니다.
저는 그와 같은 것을 찾고 있습니다.BufferedReader
Java에서 버퍼를 스트림으로 래핑하는 데 사용할 수 있습니다.
from cStringIO import StringIO # Python3 use: from io import StringIO
import sys
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
# blah blah lots of code ...
sys.stdout = old_stdout
# examine mystdout.getvalue()
Python 3.4+에는 다음과 같은 기능이 있습니다.
import io
from contextlib import redirect_stdout
with io.StringIO() as buf, redirect_stdout(buf):
print('redirected')
output = buf.getvalue()
다음은 이전 Python 버전에서 구현하는 방법을 보여주는 코드 예제입니다.
위의 Ned의 답변에 추가하자면, 이를 사용하여 쓰기(str) 메서드를 구현하는 모든 개체로 출력을 리디렉션할 수 있습니다.
이는 GUI 응용 프로그램에서 stdout 출력을 "캐치"하는 데 효과적으로 사용할 수 있습니다.
다음은 PyQt의 어리석은 예입니다.
import sys
from PyQt4 import QtGui
class OutputWindow(QtGui.QPlainTextEdit):
def write(self, txt):
self.appendPlainText(str(txt))
app = QtGui.QApplication(sys.argv)
out = OutputWindow()
sys.stdout=out
out.show()
print "hello world !"
python3의 컨텍스트 관리자:
import sys
from io import StringIO
class RedirectedStdout:
def __init__(self):
self._stdout = None
self._string_io = None
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._string_io = StringIO()
return self
def __exit__(self, type, value, traceback):
sys.stdout = self._stdout
def __str__(self):
return self._string_io.getvalue()
다음과 같이 사용:
>>> with RedirectedStdout() as out:
>>> print('asdf')
>>> s = str(out)
>>> print('bsdf')
>>> print(s, out)
'asdf\n' 'asdf\nbsdf\n'
Python 2.6부터는 API를 구현하는 모든 것을 대체하여 사용할 수 있습니다.또한 이 솔루션을 사용하면sys.stdout.buffer.write()
(이미) 인코딩된 바이트 문자열을 표준 출력에 쓸 수 있습니다(Python 3의 stdout 참조).사용.io.StringIO
안 것 같아요. 둘 다 안 되니까요, 왜하면둘다, 냐러다이.sys.stdout.buffer
도 아니다sys.stdout.encoding
가능할 것 같습니다.
다을사용솔루를 io.TextIOWrapper
:
import io
import sys
# Setup stdout.
old_stdout = sys.stdout
sys.stdout = io.TextIOWrapper(io.BytesIO(), sys.stdout.encoding)
# Write to stdout or stdout.buffer.
...
# Read from stdout.
sys.stdout.seek(0)
out = sys.stdout.read()
# Restore stdout.
sys.stdout.close()
sys.stdout = old_stdout
이 솔루션은 Python 2 >= 2.6 및 Python 3에서 작동합니다.
참고로 새 제품은sys.stdout.write()
유니코드 문자열만 허용하고sys.stdout.buffer.write()
바이트 문자열만 허용합니다.할 수 변경 Python 2 및에 3 실록도구코를 합니다.sys.stdout.buffer
.
그래서 가지려고sys.stdout.write()
문자열과 문자열을 할 수 . 이 유코드문문바모을수있다습니사를 사용할 수 .io.TextIOWrapper
하위 클래스:
class StdoutBuffer(io.TextIOWrapper):
def write(self, string):
try:
return super(StdoutBuffer, self).write(string)
except TypeError:
# Redirect encoded byte strings directly to buffer.
return super(StdoutBuffer, self).buffer.write(string)
퍼의인설필없요습다니는할정버을로 설정할 필요는 .sys.stdout.encoding
그러나 스크립트 출력을 테스트/테스트하는 데 이 방법을 사용하는 경우에는 도움이 됩니다.
이 메서드는 예외가 있더라도 sys.stdout을 복원합니다.또한 예외 이전의 모든 출력을 가져옵니다.
import io
import sys
real_stdout = sys.stdout
fake_stdout = io.BytesIO() # or perhaps io.StringIO()
try:
sys.stdout = fake_stdout
# do what you have to do to create some output
finally:
sys.stdout = real_stdout
output_string = fake_stdout.getvalue()
fake_stdout.close()
# do what you want with the output_string
다음을 사용하여 Python 2.7.10에서 테스트됨
다음을 사용하여 Python 3.6.4에서 테스트됨
Bob, 수정/확장 코드 실험으로 인해 어떤 의미로든 흥미로워질 수 있다고 생각되는 경우 추가됨, 그렇지 않으면 삭제하십시오.
비망록에 대한 몇 ... 실행 가능한 역학을 찾는 동안의 확장된 실험에서 출력물을 "잡는" 것에 대한 몇 가지 의견이 있습니다.
numexpr.print_versions()
에 직접<stdout>
(GUI 청소 및 디버깅 보고서로 세부 정보 수집이 필요한 경우)
# THIS WORKS AS HELL: as Bob Stein proposed years ago:
# py2 SURPRISEDaBIT:
#
import io
import sys
#
real_stdout = sys.stdout # PUSH <stdout> ( store to REAL_ )
fake_stdout = io.BytesIO() # .DEF FAKE_
try: # FUSED .TRY:
sys.stdout.flush() # .flush() before
sys.stdout = fake_stdout # .SET <stdout> to use FAKE_
# ----------------------------------------- # + do what you gotta do to create some output
print 123456789 # +
import numexpr # +
QuantFX.numexpr.__version__ # + [3] via fake_stdout re-assignment, as was bufferred + "late" deferred .get_value()-read into print, to finally reach -> real_stdout
QuantFX.numexpr.print_versions() # + [4] via fake_stdout re-assignment, as was bufferred + "late" deferred .get_value()-read into print, to finally reach -> real_stdout
_ = os.system( 'echo os.system() redir-ed' )# + [1] via real_stdout + "late" deferred .get_value()-read into print, to finally reach -> real_stdout, if not ( _ = )-caught from RET-d "byteswritten" / avoided from being injected int fake_stdout
_ = os.write( sys.stderr.fileno(), # + [2] via stderr + "late" deferred .get_value()-read into print, to finally reach -> real_stdout, if not ( _ = )-caught from RET-d "byteswritten" / avoided from being injected int fake_stdout
b'os.write() redir-ed' )# *OTHERWISE, if via fake_stdout, EXC <_io.BytesIO object at 0x02C0BB10> Traceback (most recent call last):
# ----------------------------------------- # ? io.UnsupportedOperation: fileno
#''' ? YET: <_io.BytesIO object at 0x02C0BB10> has a .fileno() method listed
#>>> 'fileno' in dir( sys.stdout ) -> True ? HAS IT ADVERTISED,
#>>> pass; sys.stdout.fileno -> <built-in method fileno of _io.BytesIO object at 0x02C0BB10>
#>>> pass; sys.stdout.fileno()-> Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# io.UnsupportedOperation: fileno
# ? BUT REFUSES TO USE IT
#'''
finally: # == FINALLY:
sys.stdout.flush() # .flush() before ret'd back REAL_
sys.stdout = real_stdout # .SET <stdout> to use POP'd REAL_
sys.stdout.flush() # .flush() after ret'd back REAL_
out_string = fake_stdout.getvalue() # .GET string from FAKE_
fake_stdout.close() # <FD>.close()
# +++++++++++++++++++++++++++++++++++++ # do what you want with the out_string
#
print "\n{0:}\n{1:}{0:}".format( 60 * "/\\",# "LATE" deferred print the out_string at the very end reached -> real_stdout
out_string #
)
'''
PASS'd:::::
...
os.system() redir-ed
os.write() redir-ed
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
123456789
'2.5'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Numexpr version: 2.5
NumPy version: 1.10.4
Python version: 2.7.13 |Anaconda 4.0.0 (32-bit)| (default, May 11 2017, 14:07:41) [MSC v.1500 32 bit (Intel)]
AMD/Intel CPU? True
VML available? True
VML/MKL version: Intel(R) Math Kernel Library Version 11.3.1 Product Build 20151021 for 32-bit applications
Number of threads used by default: 4 (out of 4 detected cores)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
>>>
EXC'd :::::
...
os.system() redir-ed
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
123456789
'2.5'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Numexpr version: 2.5
NumPy version: 1.10.4
Python version: 2.7.13 |Anaconda 4.0.0 (32-bit)| (default, May 11 2017, 14:07:41) [MSC v.1500 32 bit (Intel)]
AMD/Intel CPU? True
VML available? True
VML/MKL version: Intel(R) Math Kernel Library Version 11.3.1 Product Build 20151021 for 32-bit applications
Number of threads used by default: 4 (out of 4 detected cores)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Traceback (most recent call last):
File "<stdin>", line 9, in <module>
io.UnsupportedOperation: fileno
'''
Python 3.6에서는StringIO
그리고.cStringIO
모듈이 사라졌습니다. 사용해야 합니다.io.StringIO
대신.따라서 첫 번째 답변과 같이 이 작업을 수행해야 합니다.
import sys
from io import StringIO
old_stdout = sys.stdout
old_stderr = sys.stderr
my_stdout = sys.stdout = StringIO()
my_stderr = sys.stderr = StringIO()
# blah blah lots of code ...
sys.stdout = self.old_stdout
sys.stderr = self.old_stderr
// if you want to see the value of redirect output, be sure the std output is turn back
print(my_stdout.getvalue())
print(my_stderr.getvalue())
my_stdout.close()
my_stderr.close()
사용하다pipe()
적절한 파일 설명자에게 씁니다.
https://docs.python.org/library/os.html#file-descriptor-operations
여기 이것에 대한 또 다른 견해가 있습니다. contextlib.redirect_stdout
와 함께io.StringIO()
문서화된 것처럼 훌륭하지만, 여전히 일상적으로 사용하기에는 약간 장황합니다.하위 분류를 통해 원라이너로 만드는 방법은 다음과 같습니다.contextlib.redirect_stdout
:
import sys
import io
from contextlib import redirect_stdout
class capture(redirect_stdout):
def __init__(self):
self.f = io.StringIO()
self._new_target = self.f
self._old_targets = [] # verbatim from parent class
def __enter__(self):
self._old_targets.append(getattr(sys, self._stream)) # verbatim from parent class
setattr(sys, self._stream, self._new_target) # verbatim from parent class
return self # instead of self._new_target in the parent class
def __repr__(self):
return self.f.getvalue()
__enter__이(가) 자동으로 반환되므로 차단이 종료된 후 컨텍스트 관리자 개체를 사용할 수 있습니다.또한 __repr__ 메서드 덕분에 컨텍스트 관리자 개체의 문자열 표현은 실제로 stdout입니다.그래서 이제 당신은,
with capture() as message:
print('Hello World!')
print(str(message)=='Hello World!\n') # returns True
언급URL : https://stackoverflow.com/questions/1218933/can-i-redirect-the-stdout-into-some-sort-of-string-buffer
'programing' 카테고리의 다른 글
'Element'를 통해 Python에서 네임스페이스가 있는 XML 구문 분석나무' (0) | 2023.07.01 |
---|---|
HEAD, 마스터, 오리진의 깃 개념은 무엇입니까? (0) | 2023.07.01 |
함수에 다차원 변수 길이 배열 전달 (0) | 2023.07.01 |
Oracle에서 날짜를 포맷하고 정렬하는 방법은 무엇입니까? (0) | 2023.07.01 |
dplyr을 사용하여 중복된 요소 찾기 (0) | 2023.07.01 |