![](/img/trans.png)
[英]How to Get Output from a Print Statement of a Black Box Function in Python
[英]python: get the print output in an exec statement
我想得到一個exec(...)
的 output 這是我的代碼:
code = """
i = [0,1,2]
for j in i :
print j
"""
result = exec(code)
我怎樣才能得到打印輸出的東西? 我怎樣才能得到類似的東西:
0
1
2
問候和感謝。
由於 Python 3.4 有一個解決方案是 stdlib: https ://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout
from io import StringIO
from contextlib import redirect_stdout
f = StringIO()
with redirect_stdout(f):
help(pow)
s = f.getvalue()
在舊版本中,您可以編寫上下文管理器來處理替換標准輸出:
import sys
from io import StringIO
import contextlib
@contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
code = """
i = [0,1,2]
for j in i :
print j
"""
with stdoutIO() as s:
exec(code)
print("out:", s.getvalue())
您可以在 exec 調用期間將標准輸出重定向到字符串:
import sys
from cStringIO import StringIO
code = """
i = [0,1,2]
for j in i:
print(j)
"""
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
exec(code)
sys.stdout = old_stdout
print(redirected_output.getvalue())
import sys
from io import StringIO
code = """
i = [0,1,2]
for j in i:
print(j)
"""
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
exec(code)
sys.stdout = old_stdout
print(redirected_output.getvalue())
這是@Jochen 答案的 Py3 友好版本。 我還添加了try-except
子句以在code
出錯的情況下進行恢復。
import sys
from io import StringIO
import contextlib
@contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
code = """
i = [0,1,2]
for j in i :
print(j)
"""
with stdoutIO() as s:
try:
exec(code)
except:
print("Something wrong with the code")
print("out:", s.getvalue())
這是對弗雷德里克答案的一個小修正。 我們需要在exec()
中處理可能的異常以返回正常的stdout
。 否則我們看不到更遠的print
輸出:
code = """
i = [0,1,2]
for j in i :
print j
"""
from cStringIO import StringIO
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
try:
exec(code)
except:
raise
finally: # !
sys.stdout = old_stdout # !
print redirected_output.getvalue()
...
print 'Hello, World!' # now we see it in case of the exception above
import io, sys
print(sys.version)
#keep a named handle on the prior stdout
old_stdout = sys.stdout
#keep a named handle on io.StringIO() buffer
new_stdout = io.StringIO()
#Redirect python stdout into the builtin io.StringIO() buffer
sys.stdout = new_stdout
#variable contains python code referencing external memory
mycode = """print( local_variable + 5 )"""
local_variable = 2
exec(mycode)
#stdout from mycode is read into a variable
result = sys.stdout.getvalue().strip()
#put stdout back to normal
sys.stdout = old_stdout
print("result of mycode is: '" + str(result) + "'")
印刷:
3.4.8
result of mycode is: '7'
還提醒您,python exec(...)
是邪惡的和壞的,因為 1. 它使您的代碼變成不可讀的 goto-spaghetti。 2. 引入最終用戶代碼注入機會,以及 3. 將異常堆棧跟蹤拋入混亂,因為 exec 是由線程組成的,並且線程是壞的 mmkay。
就像是:
codeproc = subprocess.Popen(code, stdout=subprocess.PIPE)
print(codeproc.stdout.read())
應該在不同的進程中執行代碼,並通過codeproc.stdout
將輸出傳回主程序。 但我沒有親自使用它,所以如果我做錯了什么,請隨時指出:P
您可以將 exec 與 eval 結合使用以獲取列表輸出:
ExecString('i = [0,1,2]');
println(EvalStr('[j for j in i]'));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.