重载打印python

时间:2009-02-15 07:26:05

标签: python printing overloading

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

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

9 个答案:

答案 0 :(得分:57)

对于那些审阅以前过时的答案的人,从版本发布的“Python 2.6”开始,对原始海报的问题有了新的答案。

在Python 2.6及更高版本中,您可以禁用print语句以支持print函数,然后使用您自己的print函数覆盖print函数:

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__命名空间混淆。

答案 1 :(得分:31)

重载print是python 3.0的一个设计特性,用于解决你在python 2.x中缺乏这样做的能力。

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

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

答案 2 :(得分:10)

我遇到了同样的问题。

这个怎么样:

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

答案 3 :(得分:8)

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)

)

答案 4 :(得分:3)

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

答案 5 :(得分:2)

在Python 2.x中你不能,因为print不是一个函数,它是一个声明。在Python 3中,print是一个函数,所以我认为它可以被覆盖(尽管没有尝试过)。

答案 6 :(得分:1)

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

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

sys.stdout = sys.stderr

答案 7 :(得分:1)

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

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" )

答案 8 :(得分:1)

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

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

print = dprint

注意,这只适用于字符串参数为str ... YMMV

的情况