I. Background
In Python, the file object sys.stdin , sys.stdout and sys.stderr the standard input, standard output, and standard error streams that correspond to the interpreter, respectively. When the program starts, the initial values of these objects are determined by sys.__stdin__ , sys.__stdout__ and sys.__stderr__ saved, to restore the standard stream object when used for finishing (finalization).
Windows System Idle (Python GUI) by Pythonw.exe, the GUI does not have a console. Therefore, idle replaces the standard output handle with a special Pseudooutputfile object so that the script output is redirected to the Idle Terminal window (Shell). This can lead to some strange problems, such as:
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5, 20:32:19) [MSC v.1500 + bit (Intel)] on Win32type "copyright", "credits" or "license ()" For more information.>>> import sys>>> for FD in (Sys.stdin, Sys.stdout, Sys.stderr): PR int Fd<idlelib. Pyshell.pseudoinputfile object at 0x0177c910><idlelib. Pyshell.pseudooutputfile object at 0x0177c970><idlelib. Pyshell.pseudooutputfile object at 0x017852b0>>>> for FD in (sys.__stdin__, sys.__stdout__, sys.__stderr__) : Print Fd<open file ' <stdin> ', mode ' R ' at 0x00fed020><open file ' <stdout> ', Mode ' W ' at 0x00fed078& Gt;<open file ' <stderr> ', Mode ' W ' at 0x00fed0d0>>>>
You can see that it sys.__stdout__ sys.stdout is not the same as the value. When you run the above code under a normal Python interpreter, such as through the Windows console, the values are the same.
When the Print statement (statement) does not end with a comma, a newline character (linefeed) is automatically appended to the tail of the output string, otherwise a space is substituted for the additional newline character. The print statement is written to the standard output stream by default and can also be redirected to a file or other writable object (all objects that provide the Write method). In this way, you can use concise print statements instead of clumsy object.write('hello'+'\n') notation.
As seen in Python, when you call the print obj plot object, the default is equivalent to calling thesys.stdout.write(obj+'\n')
Examples are as follows:
>>> Import sys>>> print ' Hello world ' Hello world>>> sys.stdout.write (' Hello World ') hello World
Two. REDIRECT Mode
This section describes common Python standard output redirection methods. Each of these methods has advantages and disadvantages and is suitable for different scenarios.
2.1 Console Redirection
The simplest and most common way to redirect output is by using console commands. This redirection is done by the console, regardless of the python itself.
Both the Windows command Prompt (Cmd.exe) and the Linux Shell (bash, etc.) redirect output through ">" or ">>". Where, ">" means overwrite content, ">>" means append content. Similarly, "2>" can redirect standard errors. Redirecting to "nul" (Windows) or "/dev/null" (Linux) suppresses the output, neither display nor disk.
Take the Windows command prompt as an example to redirect the Python script output to a file (to shorten the space between the deleted commands):
E:\>echo print ' Hello ' > test.pye:\>test.py > Out.txte:\>type out.txthelloe:\>test.py >> Out.txte:\>type out.txthellohelloe:\>test.py > nul
Note that when you execute a Python script at the Windows command prompt, the command line does not have to start with "Python", and the Python interpreter is automatically invoked according to the script suffix. In addition, the type command directly displays the contents of a text file, similar to the Cat command of a Linux system.
When executing a python script in a Linux shell, the command line should start with "Python". You can use the Tee command in addition to the > or >> redirection. This command outputs the content to both the terminal screen and (multiple) files, and the "-a" option indicates an append write, otherwise overwrite the write. The example is as follows ( echo $SHELL or echo $0 shows the shell currently in use):
[Wangxiaoyuan_@localhost ~]$ echo $SHELL/bin/bash[wangxiaoyuan_@localhost ~]$ python-c "print ' Hello '" hello[ Wangxiaoyuan_@localhost ~]$ python-c "print ' Hello '" > Out.txt[wangxiaoyuan_@localhost ~]$ cat out.txthello[ Wangxiaoyuan_@localhost ~]$ python-c "print ' World '" >> out.txt[wangxiaoyuan_@localhost ~]$ cat OUT.txt Helloworld[wangxiaoyuan_@localhost ~]$ python-c "print ' I am '" | Tee Out.txti am[wangxiaoyuan_@localhost ~]$ python-c "print ' Xywang '" | Tee-a out.txtxywang[wangxiaoyuan_@localhost ~]$ cat out.txti amxywang[wangxiaoyuan_@localhost ~]$ python-c "Print" Hell O ' ">/dev/null[wangxiaoyuan_@localhost ~]$
If you just want to save the script output to a file, you can also use the log fetching function of the session window directly.
Note that the impact of console redirection is global and only applies to relatively simple output tasks.
2.2 Print >> redirect
This approach is based on the expanded form of the print statement, which is " print obj >> expr ". Where, obj for a file-like (especially one that provides the Write method), the standard output (sys.stdout) corresponds to none. exprwill be exported to the file object.
Examples are as follows:
Memo = Cstringio.stringio (); Serr = Sys.stderr; File = open (' OUT.txt ', ' w+ ') print >>memo, ' Stringio '; Print >>serr, ' stderr '; Print >>file, ' file ' Print >>none, Memo.getvalue ()
After the above code executes, the screen is "Serr" and "Stringio" (two lines, note the order), and the OUT.txt file is written in "files".
Visible, this way is very flexible and convenient. The disadvantage is that it is not suitable for scenarios with more output statements.
2.3 Sys.stdout redirect
Assigns a writable object (such as a File-like object) to the Sys.stdout, allowing the subsequent print statements to be output to the object. After the redirect is finished, the sys.stdout should be restored to the original default value, which is the standard output.
A simple example is as follows:
Import syssavedstdout = sys.stdout #保存标准输出流with open (' OUT.txt ', ' w+ ') as file: sys.stdout = file #标准输出重定向至文件 prin T ' This message was for file! ' Sys.stdout = savedstdout #恢复标准输出流print ' This message was for screen! '
Note that the sys.stdout initial value in Idle is the Pseudooutputfile object and sys.__stdout__ is not the same. For general purpose, this example defines a variable (savedstdout) to sys.stdout be saved, which is also dealt with later. In addition, this example does not apply to from sys import stdout an imported stdout object.
The following will customize a variety write() of File-like objects with methods to meet different needs:
Class Redirectstdout: #import OS, sys, Cstringio def __init__ (self): self.content = ' Self.savedstdout = Sys.stdou T self.memobj, self.fileobj, self.nulobj = None, none, none #外部的print语句将执行本write () method, and by current sys.stdout output def write (self, OUTSTR): #self. Content.append (outstr) self.content + outstr def tocons (self): #标准输出重定向至控制台 sys.stdout = Self.s Avedstdout #sys. __stdout__ def tomemo (self): #标准输出重定向至内存 self.memobj = Cstringio.stringio () sys.stdout = Self.memob J def tofile (self, file= ' OUT.txt '): #标准输出重定向至文件 self.fileobj = open (file, ' A + ', 1) #改为行缓冲 sys.stdout = Self.fileobj def tomute: #抑制输出 self.nulobj = open (Os.devnull, ' w ') sys.stdout = self.nulobj def restore (self): Self.content = "if self.memObj.closed! = True:self.memObj.close () if self.fileObj.closed! = true:self. Fileobj.close () if self.nulObj.closed! = True:self.nulObj.close () sys.stdout = Self.savedstdout #sys. __stdout_ _
Note that toFile() in the method, the open(name[, mode[, buffering]]) call selects a row buffer (no buffering can affect performance). This is to observe the intermediate write process, otherwise only the call close() or flush() post output will be written to the file. The disadvantage of calling the open () method internally is that it is not easy for users to customize write file rules, such as patterns (overwrite or append) and buffering (row or full buffering).
The redirect effect is as follows:
Redirobj = Redirectstdout () sys.stdout = Redirobj #本句会抑制 "Let's begin!" Output print "Let ' s begin!" #屏显 ' Hello world! ' and ' I am Xywang. ' (two lines) redirobj.tocons (); print ' Hello world! '; print ' I am xywang. ' #写入 ' How is it? ' and "Can ' t complain." (two lines) redirobj.tofile (); print ' How is you? '; print "Can ' t complain." Redirobj.tocons (); Print "What's up?" #屏显redirObj. Tomute (); print ' <Silence> ' #无屏显或写入os. System (' echo never redirect me! ') #控制台屏显 ' never redirect me! ' Redirobj.tomemo (); print ' What a pity! ' #无屏显或写入redirObj. tocons (); print ' Hello? ' #屏显redirObj. ToFile (); Print "Oh, Xywang can ' t hear Me" #该串写入文件redirObj. Restore () print ' Pop up ' #屏显
Visible, after executing the TOXXXX () statement, the standard output stream is redirected to XXXX. In addition toMute() , toMemo() the effect is similar and can suppress the output.
When using an object substitution sys.stdout , try to make sure that the object is close to the file object, especially when it comes to third-party libraries, which may use other methods of sys.stdout. In addition, the code implementation replaced by this section sys.stdout does not affect the os.popen()、os.system() os.exec*() standard I/O flow of processes created by or by the series method.
2.4 Contextual Manager (context Manager)
This section is not strictly a new redirection approach, but rather uses the Pyhton context Manager to optimize the code implementation of the upper section. With the context Manager syntax, you do not have to expose users to redirects sys.stdout .
First consider output suppression, which is implemented based on the context manager syntax:
Import sys, Cstringio, Contextlibclass dummyfile: def write (self, outstr): Pass@contextlib.contextmanagerdef Mutestdout (): savedstdout = sys.stdout sys.stdout = Cstringio.stringio () #DummyFile () try: yield except Exception: #捕获到错误时, display suppressed output (this processing is not required) content, sys.stdout = sys.stdout, savedstdout Print Content.getvalue () #; Raise #finally: sys.stdout = savedstdout
Examples of use are:
With Mutestdout (): print "I'll show up if <raise> is executed!" #不屏显不写入 raise #屏显上句 print "I ' m hidi ng myself Somewhere:) "#不屏显
Consider the more general output redirection:
Import OS, sysfrom contextlib import contextmanager@contextmanagerdef redirectstdout (newstdout): savedstdout, Sys.stdout = sys.stdout, newstdout try: yield finally: sys.stdout = savedstdout
Examples of use are:
def greeting (): print ' Hello, boss! ' With open (' OUT.txt ', "w+") as File: print "I ' m writing to you ..." #屏显 with redirectstdout (file): print ' I hope this letter finds you well! ' #写入文件 print ' Check your mailbox. ' #屏显with Open (Os.devnull, "w+") as file, Redirectstdout (file): greeting () #不屏显不写入 print ' I deserve a pay Raise:) ' #不屏显不写入print ' Did you hear what I said? ' #屏显
Visible, the function in the with inline block and the output of the print statement are redirected. Note that the above example is not thread-safe and is primarily intended for single-threaded.
When a function is called frequently, it is recommended that the function be wrapped with an adorner. This way, you only need to modify the function definition without using the WITH statement to wrap each time the function is called. Examples are as follows:
Import sys, Cstringio, functoolsdef mutestdout (retcache=false): def Decorator (func): @functools. Wraps (func) def wrapper (*args, **kwargs): savedstdout = sys.stdout sys.stdout = Cstringio.stringio () try: ret = func (*args, **kwargs) if Retcache = = True: ret = Sys.stdout.getvalue (). Strip () finally: Sys.stdout = savedstdout return ret return wrapper return decorator
If the mutestdout parameter of the adorner is Retcache true, the external call func() function returns the contents of the print output of the function (available for display), and if the Retcache is False, the function func() 's return value (suppress output) is returned when the function is called externally.
Examples of use of mutestdout adorners are as follows:
@MuteStdout (True) def exclaim (): print ' I am proud of myself! ' @MuteStdout () def mumble (): print ' I lack confidence ... '; Return ' sad ' print exclaim (), exclaim.__name__ #屏显 ' I am proud of myself! Exclaim ' Print mumble (), mumble.__name__ #屏显 ' sad mumble '
All threads are hijacked by the mutestdout adorner during the execution of the adornment function sys.stdout . Furthermore, once the function is decorated, it cannot remove the decoration. Therefore, you should consider the scenario carefully when using the adorner.
Next, consider creating a redirectstdout adorner:
def redirectstdout (newstdout=sys.stdout): def Decorator (func): def wrapper (*args,**kwargs): Savedstdout, sys.stdout = sys.stdout, newstdout try: return func (*args, **kwargs) finally: Sys.stdout = savedstdout return wrapper return decorator
Examples of use are:
File = open (' OUT.txt ', "w+") @RedirectStdout (file) def funnoarg (): print ' No argument. ' @RedirectStdout (file) def funonearg (a): print ' one argument: ', Adef Funtwoarg (A, b): print ' Both arguments:%s,%s '% (A, b) Fu Nnoarg () #写文件 ' No argument. ' Funonearg (1984) #写文件 ' one argument:1984 ' Redirectstdout () (Funtwoarg) (10,29) #屏显 ' both Arguments:10, "Print funnoarg.__name__ #屏显 ' wrapper ' (should show ' Funnoarg ') file.close ()
Note that the FunTwoArg() definition and invocation of a function differs from other functions, which are two equivalent syntaxes. In addition, the Redirectstdout adorner's most inner function wrapper() is not "decorated" functools.wraps(func)" , which loses the special attributes (such as function name, document string, etc.) that are used by the adornment function.
2.5 Logging Module Redirection
For projects with a large code size, it is recommended to use the logging module for output. The module is thread-safe and can output log information to the console, write files, send to the network using the TCP/UDP protocol, and so on.
By default, the logging module outputs logs to the console (standard error) and only displays logs that are greater than or equal to the logging level set. The log level is from high to low CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET and the default level is warning.
The following example prints the log information to the console and writes the file separately:
Import Logginglogging.basicconfig (level = logging. DEBUG, format = '% (asctime) s [% (LevelName) s] at% (filename) s,% (lineno) d:% (message) s ', datefmt = '%y-%m-%d (%a) %h:%m:%s ', filename = ' out.txt ', FileMode = ' W ') #将大于或等于INFO级别的日志信息输出到StreamHandler (default is standard error) Console = Logging . Streamhandler () console.setlevel (logging.info) formatter = logging. Formatter (' [% (levelname) -8s]% (message) s ') #屏显实时查看 without Time Console.setformatter (Formatter) Logging.getlogger (). AddHandler (console) logging.debug (' gubed '); Logging.info (' Ofni '); Logging.critical (' Lacitirc ')
By setting different level parameters for multiple handler, different log contents can be entered in different places. This example uses the built-in Streamhandler (and Filehandler) on the logging module, which is displayed on the screen after the run:
[INFO ] Ofni[critical] Lacitirc
The contents of the OUT.txt file are:
2016-05-13 (Fri) 17:10:53 [DEBUG] at test.py,25:gubed2016-05-13 (Fri) 17:10:53 [INFO] at test.py,25:ofni2016-05-13 (Fri) 17:10:53 [CRITICAL] at Test.py,25:lacitirc
In addition to setting logger, Handler, formatter directly in the program, you can also write this information to the configuration file. Examples are as follows:
#logger. conf############## #Logger ###############[loggers]keys=root,logger2f,logger2cf[logger_root]level= DEBUGHANDLERS=HWHOLECONSOLE[LOGGER_LOGGER2F]HANDLERS=HWHOLEFILEQUALNAME=LOGGER2FPROPAGATE=0[LOGGER_LOGGER2CF] handlers=hpartialconsole,hpartialfilequalname=logger2cfpropagate=0############## #Handler ###############[ handlers]keys=hwholeconsole,hpartialconsole,hwholefile,hpartialfile[handler_hwholeconsole]class= Streamhandlerlevel=debugformatter=simpformatterargs= (Sys.stdout,) [handler_hpartialconsole]class= Streamhandlerlevel=infoformatter=simpformatterargs= (Sys.stderr,) [handler_hwholefile]class=filehandlerlevel= debugformatter=timeformatterargs= (' OUT.txt ', ' a ') [handler_hpartialfile]class=filehandlerlevel=warningformatter= timeformatterargs= (' OUT.txt ', ' W ') ############## #Formatter ###############[formatters]keys=simpformatter, timeformatter[formatter_simpformatter]format=[% (LevelName) s] at (filename) s,% (lineno) d:% (message) S[formatter_ timeformatter]format=% (asctime) s [% (LevelName) s] at% (fileName) s,% (Lineno) d:% (message) sdatefmt=%y-%m-%d (%a)%h:%m:%s
A total of three logger:root are created here, all logs are output to the console, logger2f all logs are written to the file, LOGGER2CF, logs with a level greater than or equal to info are output to the console, and logs written to the file with a level greater than or equal to warning.
The program parses the configuration file and redirects output in the following ways:
Import logging, Logging.configlogging.config.fileConfig ("logger.conf") logger = Logging.getlogger ("LOGGER2CF") Logger.debug (' gubed '); Logger.info (' Ofni '); Logger.warn (' Nraw ') logger.error (' Rorre '); Logger.critical (' Lacitirc ') Logger1 = Logging.getlogger ("logger2f") logger1.debug (' gubed '); Logger1.critical (' Lacitirc ') Logger2 = Logging.getlogger () logger2.debug (' gubed '); Logger2.critical (' Lacitirc ')
After running the screen is displayed:
[INFO] at test.py,7:ofni[warning] at Test.py,7:nraw[error] @ test.py,8:rorre[critical] at Test.py,8:lacitirc[debug] A T test.py,14:gubed[critical] at TEST.PY,14:LACITIRC
The contents of the OUT.txt file are:
2016-05-13 (Fri) 20:31:21 [WARNING] at test.py,7:nraw2016-05-13 (Fri) 20:31:21 [ERROR] at test.py,8:rorre2016-05-13 (Fri) 20:31:21 [CRITICAL] at test.py,8:lacitirc2016-05-13 (Fri) 20:31:21 [DEBUG] at test.py,11:gubed2016-05-13 (Fri) 20:31:21 [ CRITICAL] at Test.py,11:lacitirc
Three. Summary
The above is about the Python standard output redirection mode of all content, hope to learn Python friends can help, if there is doubt welcome message to discuss.