【问题标题】:overload print python重载打印python
【发布时间】:2010-10-07 17:16:45
【问题描述】:

我能否重载print 函数并从内部调用正常函数?我想做的是在我希望print 调用我的print 的特定行之后,这将调用普通的print 并将副本写入文件。

我也不知道如何重载print。我不知道如何做可变长度参数。我会尽快查找,但 overload print python 刚刚告诉我,我不能在 2.x 中重载 print,这正是我正在使用的。

【问题讨论】:

    标签: python printing overloading


    【解决方案1】:

    对于那些查看以前过时的答案的人,从“Python 2.6”版本开始,对原始发布者的问题有一个新的答案。

    在 Python 2.6 及更高版本中,您可以禁用打印语句以支持打印功能,然后用您自己的打印功能覆盖打印功能:

    from __future__ import print_function
    # This must be the first statement before other statements.
    # You may only put a quoted or triple quoted string, 
    # Python comments, other future statements, or blank lines before the __future__ line.
    
    try:
        import __builtin__
    except ImportError:
        # Python 3
        import builtins as __builtin__
    
    def print(*args, **kwargs):
        """My custom print() function."""
        # Adding new arguments to the print function signature 
        # is probably a bad idea.
        # Instead consider testing if custom argument keywords
        # are present in kwargs
        __builtin__.print('My overridden print() function!')
        return __builtin__.print(*args, **kwargs)
    

    当然,此时您需要考虑此打印功能仅适用于模块范围。您可以选择覆盖__builtin__.print,但您需要保存原始__builtin__.print;可能会与 __builtin__ 命名空间混淆。

    【讨论】:

    • 如果我尝试在 Python 2.7.3 中使用此函数,我会收到 line 7, in print return __builtins__.print(*args, **kwargs) AttributeError: 'dict' object has no attribute 'print' 错误。可能是什么问题?
    • 嗯...我用 Python 2.7.2 对其进行了测试,它工作正常。我注意到 Python 2.7.4 刚刚发布,并且有一些关于 _ _future _ _ 和 print_function 的错误修复查看 hg.python.org/cpython/file/9290822f2280/Misc/NEWS 我也没有测试 2.7.4。
    • 您应该先使用import __builtin__,然后使用__builtin__.print,而不是使用__builtins__see the explanation here
    • 感谢您注意到 rczajka。但是在 Python 3.x 中,__builtin__ 已被重命名。它现在不能以那种形式使用。签出:Post
    • 注意:它对 Python 2 中使用 print 语句的其他模块没有影响。
    【解决方案2】:

    重载print 是python 3.0 的一项设计功能,旨在解决您在python 2.x 中缺乏这样做的能力。

    但是,您可以覆盖 sys.stdout。 (example.) 只需将其分配给另一个类似文件的对象即可。

    或者,您可以通过 unix tee 命令通过管道传输您的脚本。 python yourscript.py | tee output.txt 将打印到 stdout 和 output.txt,但这会捕获所有输出。

    【讨论】:

      【解决方案3】:
      class MovieDesc:
          name = "Name"
          genders = "Genders"
          country = "Country"
      
       def __str__(self):
      #Do whatever you want here
              return "Name: {0}\tGenders: {1} Country: {2} ".format(self.name,self.genders,self.country)
      
      )
      

      【讨论】:

      • 我想知道这是什么。它与问题无关。
      • @Scheintod 哦,真的吗? :D
      【解决方案4】:

      我遇到了同样的问题。

      这个怎么样:

      class writer :
          def __init__(self, *writers) :
              self.writers = writers
      
          def write(self, text) :
              for w in self.writers :
                  w.write(text)
      
      import sys
      
      saved = sys.stdout
      fout = file('out.log', 'w')
      sys.stdout = writer(sys.stdout, fout)
      print "There you go."
      sys.stdout = saved
      fout.close()
      

      它对我来说就像一个魅力。 取自http://mail.python.org/pipermail/python-list/2003-February/188788.html

      【讨论】:

      • saved = sys.stdout 是不必要的,sys.__stdout__ 总是保留原来的stdout,所以最后只做sys.stdout = sys.__stdout__
      • 保存 sys.stdout 允许您链接覆盖;如果您直接写入 sys.__stdout__ 您将绕过任何日志框架或您尝试注入程序的此类框架。最好显式保存 stdout 的先前值。
      • 使用file() 而不是open() 打开日志有什么特殊原因吗? The documentation recommends against that.
      【解决方案5】:

      在 Python 2.x 中你不能,因为 print 不是一个函数,它是一个语句。在 Python 3 中 print 是一个函数,所以我想它可以被覆盖(虽然没有尝试过)。

      【讨论】:

        【解决方案6】:

        虽然您不能替换 print 关键字(在 Python 2.x 中 print 是一个关键字),但通常的做法是替换 sys.stdout 以执行类似于 print 覆盖的操作;例如,StringIO.StringIO 的实例。这将捕获StringIO 实例中的所有打印数据,之后您可以对其进行操作。

        【讨论】:

          【解决方案7】:

          我回答了同样的问题on a different SO question

          本质上,最简单的解决方案是将输出重定向到 stderr,如下所示,在 wsgi 配置文件中。

          sys.stdout = sys.stderr
          

          【讨论】:

            【解决方案8】:

            只是想我会添加我的想法...适合我能够在 Eclipse 中运行 sthg 然后从 (Windows) CLI 运行而不会在每个打印语句中出现编码异常的目的。 无论您做什么,都不要使 EncodingStdout 成为类文件的子类:“self.encoding = encoding”行将导致编码属性为无!

            NB 我在与这些东西搏斗的一天中发现的一件事是,在“打印”或“写入”之前引发了编码异常:这是在参数化字符串(即“mondodod %s blah blah %s " % ( "blip", "blap" )) 是由……什么构成的??? “框架”?

            class EncodingStdout( object ):
                def __init__( self, encoding='utf-8' ):
                    self.encoding = encoding
            
                def write_ln( self, *args ):
                    if len( args ) < 2:
                        sys.__stdout__.write( args[ 0 ] + '\n' )
                    else:
                        if not isinstance( args[ 0 ], basestring ):
                            raise Exception( "first arg was %s, type %s" % ( args[ 0 ], type( args[ 0 ]) ))
                        # if the default encoding is UTF-8 don't bother with encoding
                        if sys.getdefaultencoding() != 'utf-8':
                            encoded_args = [ args[ 0 ] ]
                            for i in range( 1, len( args )):
                                # numbers (for example) do not have an attribute "encode"
                                if hasattr( args[ i ], 'encode' ):
                                    encoded_args.append( args[ i ].encode( self.encoding, 'replace' ) )
                                else:
                                    encoded_args.append( args[ i ])
                            args = encoded_args
                        sys.__stdout__.write( args[ 0 ] % tuple( args[ 1 : ] ) + '\n' )
                    # write seems to need a flush
                    sys.__stdout__.flush()
            
                def __getattr__( self, name ):
                    return sys.__stdout__.__getattribute__( name )
            
            print "=== A mondodod %s %s" % ( "été", "pluviôse, irritée contre la ville entière" ) 
            
            
            sys.stdout = EncodingStdout()
            sys.stdout.write_ln( "=== B mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )
            
            # convenience method
            def pr( *args ):
                sys.stdout.write_ln( *args )
            
            pr( "=== C mondodod %s %s", "été", "pluviôse, irritée contre la ville entière" )
            

            【讨论】:

              【解决方案9】:

              举一个非常简单的例子,从 Python3.4 开始(尚未使用旧版本进行测试),这对我来说效果很好(放在模块的顶部):

              import time
              def dprint(string):
                __builtins__.print("%f -- %s" % (time.time(), string))
              
              print = dprint
              

              注意,这仅适用于字符串参数是 str... YMMV

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-06-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-01-02
                相关资源
                最近更新 更多