首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >覆盖内置函数

覆盖内置函数
EN

Stack Overflow用户
提问于 2013-12-13 13:17:19
回答 4查看 14.5K关注 0票数 10

我有大量使用"print“语句的代码。以这种方式说:

代码语言:javascript
运行
复制
print "foo"

而不是

代码语言:javascript
运行
复制
print("foo")

我想改变输出。我能做到这一点,而不改变所有的线条与打印?例如,通过覆盖函数/语句?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-12-13 13:32:01

这会改变print语句的行为,而不会强迫您更改

print "foo"

代码语言:javascript
运行
复制
print("foo")

代码语言:javascript
运行
复制
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

收益率

代码语言:javascript
运行
复制
Foo : 'Hi'

这可以与上下文管理器保持一致,但是如果您不想将print语句更改为print函数,您可能也不必将print语句包装在上下文管理器中。

所以,一个更好、更文明的方法就是使用

代码语言:javascript
运行
复制
2to3 --write  --fix print test.py

自动将代码中的所有print语句(例如,上面的test.py )更改为print函数。然后,您可以通过重新定义print函数来改变行为:

代码语言:javascript
运行
复制
from __future__ import print_function
import __builtin__

def print(*args, **kwargs): 
    __builtin__.print('Foo:', *args, **kwargs)
print('Hi')

收益率

代码语言:javascript
运行
复制
Foo: Hi
票数 9
EN

Stack Overflow用户

发布于 2013-12-13 13:25:01

Python 直接支持您想要做的事情:

代码语言:javascript
运行
复制
from __future__ import print_function

任何顶部有一行代码的模块都会将print语句作为一个函数来处理,从而使代码与Python2和3兼容。

这将只应用于到print语句;您不能覆盖其他语句。

这确实意味着您必须在该模块中的任何地方使用print()作为函数,但如果您愿意,也可以提供您自己的实现:

代码语言:javascript
运行
复制
from __future__ import print_function
import __builtin__

def print(*args, **kwargs):
    __builtin__.print('Prefixed:', *args, **kwargs)

print('Hello world!')

另一种选择是使用上下文管理器捕获打印语句,将输出从sys.stdout引导到您选择的内存中文件对象:

代码语言:javascript
运行
复制
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

并将想要捕获print输出的任何块与上下文管理器包装起来。下面是打印行的前缀示例:

代码语言:javascript
运行
复制
with capture_sys_output as output:
    print 'Hello world!'

output = output.get_value()
for line in output.splitlines():
    print 'Prefixed:', line

或者甚至提供一个包装:

代码语言:javascript
运行
复制
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

并用作:

代码语言:javascript
运行
复制
with prefix_stdout('Prefixed: '):
    print 'Hello world!'

但是,考虑到print语句通常以不同的块将数据写入stdout;最后的换行符是单独的写。

票数 15
EN

Stack Overflow用户

发布于 2013-12-13 13:24:35

在Python2.x中,print是一个语句,因此可以在没有父类的情况下调用它。很明显你在用这个。

不能覆盖内置的print语句。

但是,它将其输出写入sys.stdout。也许您可以用具有sys.stdout方法的对象覆盖.write,如下所示:

代码语言:javascript
运行
复制
import sys
from StringIO import StringIO

s = StringIO()
sys.stdout = s

print "Hmmm."

assert s.getvalue() == "Hmmm.\n"
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20567497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档