轉(zhuǎn)自:http://blog.csdn.net/wuxiushu/article/details/52358172
sys.stdout?與print??
當(dāng)我們在?Python?中打印對象調(diào)用print?obj?時候,事實上是調(diào)用了?sys.stdout.write(obj+'\n')??
print?將你需要的內(nèi)容打印到了控制臺,然后追加了一個換行符。print?會調(diào)用?sys.stdout?的?write?方法??
以下兩行在事實上等價:??
sys.stdout.write('hello'+'\n')???
print?'hello'??
sys.stdin?與?raw_input??
當(dāng)我們用?raw_input('Input?promption:?')?時,事實上是先把提示信息輸出,然后捕獲輸入??
以下兩組在事實上等價:??
hi=raw_input('hello??')? ?
print?'hello??',?#comma?to?stay?in?the?same?line???
hi=sys.stdin.readline()[:-1]?#?-1?to?discard?the?'\n'?in?input?stream??
從控制臺重定向到文件??
原始的?sys.stdout?指向控制臺??
如果把文件的對象的引用賦給?sys.stdout,那么print?調(diào)用的就是文件對象的?write?方法??
f_handler=open('out.log',?'w')???
sys.stdout=f_handler???
print?'hello'??
#?this?hello?can't?be?viewed?on?concole???
#?this?hello?is?in?file?out.log??
記住,如果你還想在控制臺打印一些東西的話,最好先將原始的控制臺對象引用保存下來,向文件中打印之后再恢復(fù)?sys.stdout??
__console__=sys.stdout???
#?redirection?start?#???
...???
#?redirection?end???
sys.stdout=__console__??
同時重定向到控制臺和文件??
如果我們希望打印的內(nèi)容一方面輸出到控制臺,另一方面輸出到文件作為日志保存,那么該怎么辦???
將打印的內(nèi)容保留在內(nèi)存中,而不是一打印就將?buffer?釋放刷新,那么放到一個字符串區(qū)域中會怎樣???
a=''???
sys.stdout=a???
print?'hello'??
OK,上述代碼是無法正常運行的??
Traceback?(most?recent?call?last):?File???
".\hello.py",?line?xx,?in?print?'hello'???
AttributeError:'str'???
object?has?no?attribute'write'??
錯誤很明顯,就是上面強調(diào)過的,在嘗試調(diào)用?sys.stdout.write()?的時候,發(fā)現(xiàn)沒有?write?方法??
另外,這里之所以提示?attribute?error?而不是找不到函數(shù)等等,我猜想是因為?python?將對象/類的函數(shù)指針記錄作為對象/類的一個屬性來對待,只是保留了函數(shù)的入口地址??
既然這樣,那么我們必須給重定向到的對象實現(xiàn)一個?write?方法:??
import?sys???
class?__redirection__:???
def?__init__(self):???
self.buff=''???
self.__console__=sys.stdout???
def?write(self,?output_stream):???
self.buff+=output_stream???
def?to_console(self):???
sys.stdout=self.__console__???
print?self.buff???
def?to_file(self,?file_path):??
f=open(file_path,'w')???
????sys.stdout=f???
print?self.buff???
????f.close()???
def?flush(self):???
self.buff=''???
def?reset(self):???
sys.stdout=self.__console__???
if?__name__=="__main__":???
#?redirection???
??r_obj=__redirection__()???
??sys.stdout=r_obj??
#?get?output?stream???
print?'hello'???
print?'there'???
#?redirect?to?console???
??r_obj.to_console()???
#?redirect?to?file???
r_obj.to_file('out.log')???
#?flush?buffer??
??r_obj.flush()???
#?reset???
??r_obj.reset()??
同樣的,sys.stderr,?sys.stdin?也都可以被重定向到多個地址,舉一反三的事情就自己動手實踐吧 ?