如何";超载“;python';“s打印功能”;全球范围内;?

如何";超载“;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():

我使用的是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():
    global print
    print = NewPrint

OverloadPrint()
print("ha")
它很好用。“重载”打印的输入位于NewPrint指定的文件中

现在考虑到这一点,我希望能够运行上面的两行,让print在整个脚本执行过程中执行NewPrint所做的事情。现在,如果我从另一个使用print的模块调用函数,它将使用内置的print,而不是我刚刚重写的print。我想这与名称空间和内置程序有关,但我的python不够好

编辑:

我试着保持简单,但看起来这引起了更多的混乱

  • 重载打印的函数将打印到GUI,因此如果函数重载,则无需关心重定向
  • 我知道我的示例没有执行打印函数实际执行的操作。一个更好的例子说明了我是如何对其进行编码的(据我所知仍然不是很好):

  • > p>从上面2中你可以看到我必须用来打印到GUI“HLILIAL”的函数,它是通过Sigg包装器公开的C++函数。

  • 我们只使用标准库和我们自己的swig包装器,我们的开发人员也使用print作为函数(习惯于3.X)。因此,我并不担心其他模块调用print并使用其他模块

  • 从所有的评论来看,我想仅仅使用一些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/第三方/同事/等。您调用的代码将在进行更改之前检查
      stdout
      是否为tty,并将其自身配置为交互式输出
    • 有些代码会在您有机会重定向之前打印出来,您将花费数小时试图找出如何重新排序以解决问题
    • 你必须知道如何完全实现一个“类似文件的对象”,这个概念在2.6中没有完全定义,否则它会被一些代码破坏
    • 在某个地方,有一些你认为是打印的代码,但实际上,比如说,它是正在写入或写入sys.stderr或做其他事情,所以你给了自己一种错误的安全感,你现在把所有东西都记录在
      somefile.txt
      ,直到6个月后,当您迫切需要丢失的信息来调试客户站点上的问题时,才会发现其他问题
    由于您已编辑了该问题,下面是一些进一步的回答:

    从所有的评论中,我猜只是使用了一些print_u2;()函数而不是print()

    是的,这是一个更合理的选择。但我可能不会称之为
    打印
    。将“做或不做”逻辑放在函数中会更简单,而不是在全局名称中交换实现(特别是因为如果代码不都在一个大模块中,您会在某个时候搞砸)

    我在一个项目中使用了一个类似的用例:我们有要转到系统日志的消息,如果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)