我正在使用python 2.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指定的文件中。

现在考虑到这一点,我希望能够在上面的两行中运行并进行打印,以便在脚本的整个执行过程中执行NewPrint的操作。现在,如果我从另一个使用print的模块中调用一个函数,它将使用内置的print而不是我刚刚改写的print。我想这与 namespace 和内置函数有关,但是我的python不够好。

编辑:

我试图保持简单,但是看起来这引起了更多的困惑。
  • 重载print的函数将打印到GUI,因此无需关心重定向如果重载了该函数。
  • 我知道我的示例并没有执行打印功能实际执行的操作。我想如何编码的一个更好的例子是(我仍然知道那还不是很好):
    def hli_print(*args, **kw):
        """
        print([object, ...], sep=' ', end='\n', file=sys.stdout)
        """
        sep = kw.get('sep', ' ')
        end = kw.get('end', '\n')
        File = kw.get('file', sys.stdout)
        args = [str(arg) for arg in args]
        string = sep.join(args) + end
        File.write(string)
        hli_Print(string)
    
  • 从上面的2中,您可以看到我必须用于打印到GUI“hli_Print”的函数,它是通过Swig包装程序公开的C++函数。
  • 我们仅使用标准库和我们自己的swig包装器,我们的开发人员也将print作为函数使用(习惯了3.X)。因此,我并不真正担心其他一些调用print并具有其他功能的模块。

  • 从所有评论中,我猜想仅仅使用一些print_()函数而不是print()(这是我们当前正在做的)可能是最好的,但是我真的很好奇,看看在python中是否可以做我想做的事情描述。

    最佳答案

    我认为您的问题没有任何意义。

    首先,如果您正在运行Python 2.6,即使您自己的模块正在使用print函数,导入的所有内容等都将使用print语句。因此,重载该功能不会影响其他任何内容。

    其次,您说“我需要这样做,因为此代码可能在必须使用内置函数来生成输出的系统上使用,否则将不显示任何输出。”好吧,您的NewPrint不是内置函数,因此仍然无济于事。

    还需要注意的是,您的NewPrint并未实现print函数的大部分功能,即使它确实实现了该功能,它也会出错(print(s)将先打印s,然后再换行)。因此,如果确实用内置print函数替换了sys.stdout函数,则最终将破坏大多数自己的代码以及您依赖的任何stdlib/第三方代码。

    您可能可以通过创建一个替换>>的类似文件的对象来完成所需的操作。否则,我看不到任何方法。例如:

    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 有缺陷的平台上,这有时是一个方便的主意。但是否则,从长远来看,这可能会给您带来比提供更好的解决方案更多的麻烦。这只是几处可能出错的地方(仅作为示例,并非详尽的 list )
  • 如果您想更改输出到的文件,则必须修改脚本。如果您在 shell 中使用stdout,则可以不同地调用该脚本。
  • 有人正在阅读或调试您的代码(例如,您忘记了代码的工作三个月之后),会对发生的事情感到惊讶。
  • 一些stdlib/third-party/coworker/etc。进行更改之前,您调用的代码将检查print是否为tty,并对其进行配置以进行交互式输出。
  • 在您有机会进行重定向之前,将打印一些代码,并且您将花费数小时试图弄清楚如何重新排列事情以解决问题。
  • 您必须知道如何完全实现“类文件的对象”,并且该概念在2.6中尚未完全定义,否则它将被某些代码破坏。
  • 在某个地方,您认为有一些代码是log ing,但实际上是说sys.stderr ging或写到somefile.txt或执行其他操作,因此您给自己一种错误的安全感,您现在正在将所有内容都记录在其中print_,直到6个月后才发现,否则当您迫切需要缺少的信息来在客户现场调试问题时。

  • 既然您已经编辑了问题,这里有一些进一步的回答:



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

    我在一个具有类似用例的项目上工作:我们收到了一些消息,我们想转到系统日志,如果打开的话,还要转到GUI的“日志窗口”。因此,我们编写了一个print函数,将其包装起来,没有人提示他们想编写print。 (实际上,团队中至少有一个人很高兴他可以在调试时使用logging进行快速,肮脏的打印输出而不影响实际输出,尤其是当他必须调试GUI日志记录代码时。)

    但这仅仅是因为我们对新的logging模块(当时)没有任何经验。如今,我认为我将创建一个写入gui窗口的Handler logging实现,然后添加该处理程序,并在各处使用标准__future__方法。听起来这可能是您的最佳选择。

    另外,最后一个可能不相关的附带问题是:



    那么,为什么不首先使用3.x?显然,3.x具有实际的3.x标准库,而不是某种类似于3.x标准库(如果您执行一些ojit_code语句的话),而SWIG可与3.x一起使用…

    关于python - 如何 "overload"python的打印函数 "globally"?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13870928/

    10-11 22:33
    查看更多