是否可以在Python中暂时重定向stdout/stderr(即在方法的持续时间内)?
当前解决方案(我最初记得但后来忘记了)的问题在于它们没有重定向 ; 相反,他们只是完整地替换了流.因此,如果一个方法有一个本地副本,一个变量的任何原因(例如,由于流被作为参数传递的东西),它不会工作.
有解决方案吗
我使用python lib导入一个在stdout上打印的C共享库.我想要一个干净的输出,以便与管道一起使用或重定向文件.打印是在python之外的共享库中完成的.
一开始,我的方法是:
# file: test.py
import os
from ctypes import *
from tempfile import mktemp
libc = CDLL("libc.so.6")
print # That's here on purpose, otherwise hello word is always printed
tempfile = open(mktemp(),'w')
savestdout = os.dup(1)
os.close(1)
if os.dup(tempfile.fileno()) != 1:
assert False, "couldn't redirect stdout - dup() error"
# let's pretend this is a call to my library
libc.printf("hello world\n")
os.close(1)
os.dup(savestdout)
os.close(savestdout)
Run Code Online (Sandbox Code Playgroud)
第一种方法是半工作:
- 由于某种原因,它在移动stdout之前需要一个"print"语句,否则总是打印hello word.因此,它将打印一个空行而不是库通常输出的所有模糊.
- 更令人讨厌,重定向到文件时失败:
$python test.py > foo && cat foo
hello world …Run Code Online (Sandbox Code Playgroud) 编辑:请注意我正在使用Python 2.6(标记为)
说我有以下内容:
class Foo:
def bar(self):
print 'bar'
return 7
Run Code Online (Sandbox Code Playgroud)
并说我有以下单元测试:
import unittest
class ut_Foo(unittest.TestCase):
def test_bar(self):
obj = Foo()
res = obj.bar()
self.assertEqual(res, 7)
Run Code Online (Sandbox Code Playgroud)
所以如果我跑:
unittest.main()
Run Code Online (Sandbox Code Playgroud)
我明白了:
bar # <-- I don't want this, but I *do* want the rest
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Exit code: False
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有办法抑制被测对象的输出,同时仍然得到unittest框架的输出?
编辑 此问题不是标记问题的副本,该问题询问是否在正常python脚本中对特定函数的stdout进行静默.
虽然这个问题是在运行它的单元测试时询问是否隐藏了python脚本的正常标准输出.我仍然希望显示unittest标准输出,我不想禁用我测试过的脚本的标准输出.
我正在使用tqdmPython在我们的脚本中显示控制台进度条.但是,我必须将调用print消息的函数调用到控制台,而且我无法更改.通常,在控制台中显示进度条的同时写入控制台会使显示屏变得如此:
from time import sleep
from tqdm import tqdm
def blabla():
print "Foo blabla"
for k in tqdm(range(3)):
blabla()
sleep(.5)
Run Code Online (Sandbox Code Playgroud)
这会创建输出:
0%| | 0/3 [00:00<?, ?it/s]Foo
blabla
33%|###########6 | 1/3 [00:00<00:01, 2.00it/s]Foo
blabla
67%|#######################3 | 2/3 [00:01<00:00, 2.00it/s]Foo
blabla
100%|###################################| 3/3 [00:01<00:00, 2.00it/s]
Run Code Online (Sandbox Code Playgroud)
根据tqdm该方法的文档tqdm.write()提供了一种在不破坏显示的进度条的情况下将消息写入控制台的方法.因此,此片段提供了正确的输出:
from time import sleep
from tqdm import tqdm
def blabla():
tqdm.write("Foo blabla")
for k in tqdm(range(3)):
blabla()
sleep(.5)
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
Foo blabla
Foo blabla
Foo blabla
100%|###################################| 3/3 …Run Code Online (Sandbox Code Playgroud) 好的..所以可能一个例子是解释这个问题的好方法
所以我有这样的事情:
if __name__=="__main__"
result = foobar()
sys.stdout.write(str(result))
sys.stdout.flush()
sys.exit(0)
Run Code Online (Sandbox Code Playgroud)
现在这个脚本是从ruby脚本调用的..基本上它在那里解析结果.但是foobar()有很多打印声明..而且stdout也刷新了所有这些打印件.有没有办法(除了记录mathods)我可以在这里修改一些自动抑制那些打印的东西,只是刷新这个结果?谢谢
问题:从现有argparse.ArgumentParser对象访问可能的参数的预期/官方方式是什么?
示例:我们假设以下上下文:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', '-f', type=str)
Run Code Online (Sandbox Code Playgroud)
在这里,我想获得以下允许参数列表:
['-h', '--foo', '--help', '-f']
Run Code Online (Sandbox Code Playgroud)
我找到了以下解决方法,它为我提供了诀窍
parser._option_string_actions.keys()
Run Code Online (Sandbox Code Playgroud)
但我对此并不满意,因为它涉及访问_未正式记录的成员.什么是这项任务的正确选择?
使用机器学习库PyML时,我遇到了一个恼人的问题.PyML使用libsvm来训练SVM分类器.问题是libsvm将一些文本输出到标准输出.但因为那是在Python之外我不能拦截它.我尝试使用问题中描述的方法在Python中静默函数的标准输出,而不会破坏sys.stdout并恢复每个函数调用,但这些都没有帮助.
有什么方法可以做到这一点.修改PyML不是一种选择.
严格按照文档中的示例完成此错误.并且你无法在任何地方找到任何关于它的澄清,无论是长篇文档页面,google还是stackoverflow.另外,阅读optparse.py显示OptionGroup在那里,这增加了混乱.
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
>>> from optparse import OptionParser
>>> outputGroup = OptionGroup(parser, 'Output handling')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'OptionGroup' is not defined
Run Code Online (Sandbox Code Playgroud)
我敢打赌,有人发现我的错误不到1分钟.:)
是的,这意味着我知道答案,但是因为这花了我很长时间才发现我想在这里"记录"它.
当我运行程序时,使用的是:
nltk.download('wordnet')
from nltk.corpus import wordnet
Run Code Online (Sandbox Code Playgroud)
我将以下输出发送到终端:
[nltk_data] Downloading package wordnet to
[nltk_data] /Users/.../nltk_data...
[nltk_data] Package wordnet is already up-to-date!
Run Code Online (Sandbox Code Playgroud)
我的程序依赖于未将此信息保存到终端和结果输出文件中,因此,如何防止上述行发生或将其写入,以sys.stderr使其不被包含而不是通过传递print呢?
使用 openpyxl for python 加载 xlsm 文件时收到警告,然后在将一些数据添加到特定工作表中的特定 7 个单元格后保存/关闭它。问题是我收到了一个“FutureWarning”,我不知道它是关于什么的。我已经搜索了一段时间,但无法破译。
我怀疑 wb.save() 方法是触发此警告的原因,因为当我评论此特定行时它没有显示。
有谁知道这是什么?
代码
wb = openpyxl.load_workbook(filename=directory_path.xlsm, keep_vba=True)
ws = wb['sheetname']
ws.cell(row1, col1).value = ### (some number)
ws.cell(row2, col2).value = ### (some number)
ws.cell(row3, col3).value = ### (some number)
ws.cell(row4, col4).value = ### (some number)
ws.cell(row5, col5).value = ### (some number)
ws.cell(row6, col6).value = ### (some number)
ws.cell(row7, col7).value = ### (some number)
wb.save(directory_path.xlsm)
wb.close()
Run Code Online (Sandbox Code Playgroud)
警告信息
C:\Users\...\Anaconda3\lib\site-packages\openpyxl\comments\shape_writer.py:75: FutureWarning: The behavior of this method will change in future versions. Use specific …Run Code Online (Sandbox Code Playgroud) 我有一些使用多处理 Pool 类并行运行的代码。不幸的是,我从另一个库中使用的一些函数有一些冗长的输出。要抽象问题,请查看以下示例:
from multiprocessing import Pool
def f(x):
print 'hello'
return x*x
p = Pool(10)
p.map(f, [1,2,3])
Run Code Online (Sandbox Code Playgroud)
所以这将打印 'hello' 10 次。是否有可能使进程的输出静音或将 std.out 放在某个变量中?感谢您的任何建议。
编辑:我不想重定向整个标准输出,只是为了我的池进程。
python ×11
stderr ×2
argparse ×1
ctypes ×1
libsvm ×1
nameerror ×1
nlp ×1
nltk ×1
openpyxl ×1
optparse ×1
pyml ×1
python-2.6 ×1
python-2.7 ×1
python-2.x ×1
python-3.x ×1
redirect ×1
stdout ×1
tqdm ×1