2014-02-12 93 views
2

我有一個Python中的函數,它需要一個「閱讀器」(我希望這是正確的術語)。基本上,函數應該能夠使用文件,sys.stdin等。然後,它必須讀取所有行並將它們存儲在一個字符串中。閱讀從python到閱讀器的輸入字符串

目前我的函數調用看起來是這樣的:

read_data (sys.stdin, sys.stdout) 

    read_data ("file.txt", "fileout.txt") 

和本身看起來像功能:

def read_data (reader, s) : 

    str = "" 

    str = r.readline() 
    line = str 
    while line != "" and line != None and line != '\n': 
     line = r.readline() 
     str = str + line 

當我運行的代碼,輸入粘貼到控制檯來實際測試,它能夠讀取所有行,包括最後一行,但之後它會卡在「line = readline()」中。我不知道我做錯了什麼,任何幫助將不勝感激。謝謝

+0

FWIW我認爲你要找的術語是'IO'對象。 [Duck-wise](http://en.wikipedia.org/wiki/Duck_typing),你基本上在尋找任何實現['readline']的對象(http://docs.python.org/2/library /io.html#io-base-classes) – kojiro

+0

如果你在windows上,你可能需要添加'和line!='\ r \ n''。爲了簡單起見,你可能需要將if改爲'if'in line in [「」,...]:' –

+0

@LaurIvan我建議將檢測到文件結尾檢測到操作系統,即。到python庫。上面的解決方案也會在滿足空行時停止讀取輸入文件,即。不在EOF。猜猜這是OP的意圖。 –

回答

1

的文件需要閱讀之前先開,如:

f = open(reader, "r") 
text = f.readline() 

^此外,儘量不要用保留關鍵字「STR」

+0

如果reader是sys.stdin,open將會失敗 –

+0

問題的一部分是有時fd已經打開。 – kojiro

+0

感謝關於str的提示(我實際上使用s,只是把str放在問題中)。 是的,問題出現,因爲我也用sys.stdin調用函數。 –

0

在一種情況下,你傳遞一個打開文件描述符sys.stdin。在另一箇中,你傳遞一個字符串。後者與您的界面不符合readline方法。您可以通過幾種方法解決這一問題。如果測試對象具有readline方法:

if not hasattr(reader, "readline"): # and is callable, etc, etc 
    reader = open(reader, 'r') 

的try /除外

try: 
    result = reader.readline() 
except AttributeError: 
    with open(reader,'r') as realreader: 
     result = realreader.readline() 

還有其他的方法,也是如此。你應該文件,該函數本身預計IO object,如果是這樣的話。

1

我會建議重組你的程序是這樣的:

def read_data(in_stream=sys.stdin, out_stream=sys.stdout): 
    """ 
    in_srteam: stream open for reading (defaults to stdin) 
    out_stream: stream open for writing (defaults to stdout) 
    """ 

    s = ''.join([line for line in in_stream]) 
    out_stream.write(s) 
+0

是否與'''.join(in_stream.readlines())'不同'。'.join([in_stream中的行])? (我的觀點是,據我所知,所有執行'readline'的對象也實現'readlines'。) – kojiro

+0

@kojiro:你是對的;他們不是。 –

+0

@kojiro:''.join(in_stream.readlines())基本上是in_stream.read()。在理解的情況下,我可以去掉換行符或者做一些事情。 –

0

你對待像一個文件對象(或具有readline方法的對象)的字符串。如果你希望能夠傳遞字符串和文件對象,那麼你可以測試一下,看它是否是一個字符串。

def read_data (reader, s) : 
    if isinstance(reader,str): 
     reader = open(reader,"r") 
    if isinstance(s,str): 
     s = open(s,"w+") 

    str = "" #avoid using str for a variable name 

    str = r.readline() 
    line = str 
    while line != "" and line != None and line != '\n': 
     line = r.readline() 
     str = str + line 

你也可以使用hasattr測試是否傳遞的對象有選擇是否要嘗試並打開它作爲一個文件前一個readline方法。

0

如果我確實瞭解你的問題,你需要把EndOfFile放入流中。對於Unix/Linux中的交互式輸入,使用Ctrl-d(ie。^ d),在Windows Ctrl-z中。

沒有這個readline不會像您期待的那樣返回空字符串。

readline(...) 
    readline([size]) -> next line from the file, as a string. 

    Retain newline. A non-negative size argument limits the maximum 
    number of bytes to return (an incomplete line may be returned then). 
    Return an empty string at EOF.