2014-02-12 95 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.