use*_*519 9 python function built-in
我有一大堆使用"print"语句的代码.至于这样说:
print "foo"
Run Code Online (Sandbox Code Playgroud)
并不是
print("foo")
Run Code Online (Sandbox Code Playgroud)
我想改变输出.我可以在不改变所有印刷线的情况下这样做吗?例如,通过覆盖函数/语句?
Mar*_*ers 15
Python 直接支持你想要做的事情:
from __future__ import print_function
Run Code Online (Sandbox Code Playgroud)
顶部具有该行的任何模块都将该print语句视为函数,使代码与Python 2和3兼容.
这适用于只是在print陈述; 你不能覆盖其他陈述.
这意味着你必须print()在该模块中的任何地方使用函数,但如果你愿意,你也可以提供自己的实现:
from __future__ import print_function
import __builtin__
def print(*args, **kwargs):
__builtin__.print('Prefixed:', *args, **kwargs)
print('Hello world!')
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用上下文管理器捕获打印的语句,将输出引导sys.stdout到您选择的内存中文件对象:
from contextlib import contextmanager
import sys
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
@contextmanager
def capture_sys_output():
caputure_out = StringIO()
current_out = sys.stdout
try:
sys.stdout = caputure_out
yield caputure_out
finally:
sys.stdout = current_out
Run Code Online (Sandbox Code Playgroud)
并print使用上下文管理器包装要捕获输出的任何块.以下是打印行前缀的示例:
with capture_sys_output as output:
print 'Hello world!'
output = output.get_value()
for line in output.splitlines():
print 'Prefixed:', line
Run Code Online (Sandbox Code Playgroud)
甚至提供包装:
from contextlib import contextmanager
import sys
class Prefixer(object):
def __init__(self, prefix, orig):
self.prefix = prefix
self.orig = orig
def write(self, text):
self.orig.write(self.prefix + text)
def __getattr__(self, attr):
return getattr(self.orig, attr)
@contextmanager
def prefix_stdout(prefix):
current_out = sys.stdout
try:
sys.stdout = Prefixer(prefix, current_out)
yield
finally:
sys.stdout = current_out
Run Code Online (Sandbox Code Playgroud)
并用作:
with prefix_stdout('Prefixed: '):
print 'Hello world!'
Run Code Online (Sandbox Code Playgroud)
但要考虑到print语句通常将数据写入stdout单独的块中; 最后的换行符是一个单独的写.
这会更改print语句的行为,而不会强制您更改
print "foo"
至
print("foo")
Run Code Online (Sandbox Code Playgroud)
import sys
_stdout = sys.stdout
class MyStream(object):
def __init__(self, target):
self.target = target
def write(self, s):
s = 'Foo : {!r}'.format(s)
self.target.write(s)
sys.stdout = MyStream(sys.stdout)
print 'Hi'
sys.stdout = _stdout # return print to its old behavior
Run Code Online (Sandbox Code Playgroud)
产量
Foo : 'Hi'
Run Code Online (Sandbox Code Playgroud)
这可以通过上下文管理器来实现,但如果您不想将print语句更改为print函数,则可能不希望将print语句包装在上下文管理器中.
因此,使用更好,更文明的方式
2to3 --write --fix print test.py
Run Code Online (Sandbox Code Playgroud)
自动print将代码中的所有语句(例如上面的test.py)更改为print函数.然后,您可以通过重新定义print函数来更改行为:
from __future__ import print_function
import __builtin__
def print(*args, **kwargs):
__builtin__.print('Foo:', *args, **kwargs)
print('Hi')
Run Code Online (Sandbox Code Playgroud)
产量
Foo: Hi
Run Code Online (Sandbox Code Playgroud)