【发布时间】:2014-01-18 09:39:10
【问题描述】:
我想将stdout 重定向到一个文件。但这会影响raw_input。我需要将raw_input 的输出重定向到stderr 而不是stdout。我该怎么做?
【问题讨论】:
-
玩转
sys.stdout、sys.stderr和sys.stdout。
标签: python io python-2.x
我想将stdout 重定向到一个文件。但这会影响raw_input。我需要将raw_input 的输出重定向到stderr 而不是stdout。我该怎么做?
【问题讨论】:
sys.stdout、sys.stderr 和sys.stdout。
标签: python io python-2.x
raw_input 的唯一问题是它将提示打印到标准输出。与其试图拦截它,为什么不自己打印提示,并在没有提示的情况下调用raw_input,它不会向标准输出打印任何内容?
def my_input(prompt=None):
if prompt:
sys.stderr.write(str(prompt))
return raw_input()
如果你想用这个替换raw_input:
import __builtin__
def raw_input(prompt=None):
if prompt:
sys.stderr.write(str(prompt))
return __builtin__.raw_input()
(有关更多信息,请参阅__builtin__ 上的文档,raw_input 和其他 built-in functions 存储在其中的模块。您通常不必import 它,但文档中没有任何内容保证,所以最好是安全的……)
在 Python 3.2+ 中,模块被命名为 builtins 而不是 __builtin__。 (当然 3.x 一开始就没有raw_input,它被重命名为input,但同样的想法也可以用在那里。)
【讨论】:
sys.stderr.write(str(prompt)) 以使其行为更像raw_input。
__builtin__ 是正确的名称; __builtins__ 是模块级对象的 CPython 特定名称,它是 __builtin__ 或 __builtin__.__dict__。但是,我不确定__builtins__ 是否保证在没有import 的情况下存在,所以我将添加它。
__main__,但尝试不同类型的模块(像sys 这样的内置模块,像cPickle 这样的C 扩展模块,Java 和.NET 导入,普通Python 模块比如pickle,两种包)。
builtins
raw_input 可以替换。 :) 但是,是的,值得一提。
暂时将stdout重定向到stderr,然后恢复。
import sys
old_raw_input = raw_input
def raw_input(*args):
old_stdout = sys.stdout
try:
sys.stdout = sys.stderr
return old_raw_input(*args)
finally:
sys.stdout = old_stdout
【讨论】:
with swapping_stdout:。您可以轻松编写一个装饰器,将函数包装在 with 语句中。但是,如果这是您唯一要做的地方,那就不会更简单了。 (见here。)如果你想要一个通用的属性交换上下文,这很容易……但你必须将命名空间和属性名称作为字符串传递给它,比如with swapping_attr(sys, 'stdout', sys.stderr):,我不这样做认为是一种改进。 (MacroPy 可以让它变得更好,但我不会仅仅为此使用 MacroPy……)
sys.__stdout__ 而不是隐藏old_stdout。
sys.__old_stdout__ 的答案(未使用sys.__stdout__,因为在Python 3.x 中,已经有sys.__stdout__,即使这是Python-2.x 问题)
sys.__stdout__ 至少在 2.6+ 中存在(并已记录),而不仅仅是 3.x。它始终是程序开始时sys.stdout 的原始值。如果您有嵌套重定向(因为不是恢复外部重定向而是恢复原始标准输出),以这种方式使用它可能会很麻烦/危险,但是对于 OP 正在寻找的内容,我认为这很好。
使用getpass
import getpass
value=getpass.getpass("Enter Name: ")
print(value)
这会将内容value 打印到stdout,将Enter Name: 打印到stderr。
经过测试并适用于 python 2.7 和 3.6。
【讨论】: