如何";超载“;python';“s打印功能”;全球范围内;?
我使用的是Python2.6.6,需要重载默认的python打印函数。我需要这样做,因为这段代码可能用于一个系统,其中必须使用内置函数生成输出,否则不会显示输出 例如,如果您有这样一个python脚本:如何";超载“;python';“s打印功能”;全球范围内;?,python,namespaces,python-2.6,Python,Namespaces,Python 2.6,我使用的是Python2.6.6,需要重载默认的python打印函数。我需要这样做,因为这段代码可能用于一个系统,其中必须使用内置函数生成输出,否则不会显示输出 例如,如果您有这样一个python脚本: from __future__ import print_function def NewPrint(Str): with open("somefile.txt","a") as AFile: AFile.write(Str) def OverloadPrint():
from __future__ import print_function
def NewPrint(Str):
with open("somefile.txt","a") as AFile:
AFile.write(Str)
def OverloadPrint():
global print
print = NewPrint
OverloadPrint()
print("ha")
它很好用。“重载”打印的输入位于NewPrint指定的文件中
现在考虑到这一点,我希望能够运行上面的两行,让print在整个脚本执行过程中执行NewPrint所做的事情。现在,如果我从另一个使用print的模块调用函数,它将使用内置的print,而不是我刚刚重写的print。我想这与名称空间和内置程序有关,但我的python不够好
编辑:
我试着保持简单,但看起来这引起了更多的混乱
从所有的评论来看,我想仅仅使用一些print_uuz()函数而不是print()(这是我们目前所做的)可能是最好的,但我真的很好奇,看看在python中是否可以实现我所描述的功能。我认为你的问题没有任何意义 首先,如果您正在运行Python2.6,那么您导入的所有内容等都将使用
print
语句,即使您自己的模块正在使用print
函数。因此,重载函数不会影响任何其他内容
第二,你说“我需要这样做,因为这段代码可能用于一个系统,其中必须使用内置函数来生成输出,否则不会显示输出。”好吧,你的NewPrint
不是内置函数,所以这无论如何都不会有帮助
还值得注意的是,您的NewPrint
没有实现print
功能的大部分功能,甚至它实现的部分,也会出错(print(s)
将打印s
,然后是换行)。因此,如果您确实用自己的函数替换了内置的print
函数,那么您最终只会破坏您自己的大部分代码以及您所依赖的任何stdlib/第三方代码
可能您可以通过创建一个类似文件的对象来替换sys.stdout
,从而实现所需的功能。否则,我看不出任何东西是如何工作的。例如:
class FakeStdOut(object):
# … lots of other stuff to implement or inherit
def write(s):
with open("somefile.txt", "a") as f:
f.write(s)
def OverloadPrint():
sys.stdout = FakeStdOut()
但即使这样做有效,也可能不是你真正想要的。对于一个快速而肮脏的脚本,在一个有缺陷的shell的平台上,这有时是一个方便的想法。但是,从长远来看,它可能会给你带来更多的麻烦,而不是想出一个更好的解决方案。这里只是一些可能出错的事情(只是作为示例,而不是详尽的列表)
- 如果要更改输出所指向的文件,必须修改脚本。如果改为在shell中使用
,则可以用不同的方式调用脚本>
- 有人阅读或调试你的代码(比如说,你,在你忘记它是如何工作的三个月后)会对发生的事情感到惊讶
- 某些stdlib/第三方/同事/等。您调用的代码将在进行更改之前检查
是否为tty,并将其自身配置为交互式输出stdout
- 有些代码会在您有机会重定向之前打印出来,您将花费数小时试图找出如何重新排序以解决问题
- 你必须知道如何完全实现一个“类似文件的对象”,这个概念在2.6中没有完全定义,否则它会被一些代码破坏
- 在某个地方,有一些你认为是打印的代码,但实际上,比如说,它是正在写入或写入sys.stderr或做其他事情,所以你给了自己一种错误的安全感,你现在把所有东西都记录在
,直到6个月后,当您迫切需要丢失的信息来调试客户站点上的问题时,才会发现其他问题somefile.txt
打印
。将“做或不做”逻辑放在函数中会更简单,而不是在全局名称中交换实现(特别是因为如果代码不都在一个大模块中,您会在某个时候搞砸)
我在一个项目中使用了一个类似的用例:我们有要转到系统日志的消息,如果GUI“日志窗口”打开,也要转到它。所以我们编写了一个glog
函数来包装它,没有人抱怨他们想写print
。(事实上,团队中至少有一个人非常高兴,他可以在调试时使用print
快速、脏兮兮的打印输出,而不影响实际输出,特别是当他必须调试GUI日志代码时。)
但那只是因为我们没有任何使用新(当时)日志记录模块的经验。现在,我想我应该创建一个日志记录处理程序实现
class FakeStdOut(object):
# … lots of other stuff to implement or inherit
def write(s):
with open("somefile.txt", "a") as f:
f.write(s)
def OverloadPrint():
sys.stdout = FakeStdOut()
from __future__ import print_function
try:
import __builtin__ as builtins # Python 2
except ImportError:
import builtins # Python 3
_print = print # keep a local copy of the original print
builtins.print = lambda *args, **kwargs: _print("foo:", *args, **kwargs)