readline函数返回空字符串

时间:2014-12-30 13:42:45

标签: python readline

我是Python新手;没有多少C ++编程经验。我看到this问题,但它没有解决我的问题。

  

Python 2.7.9,64位AMD,Windows 7旗舰版,NTFS,管理员权限&文件上没有“只读”属性。

我想创建一个满足特定条件的字符串列表,字符串是文件的行(请参阅notepad.cc/diniko93)。所以我写了以下函数 -

def makeLineList( filePtr, ptr ):
    lines = []
    while True:
        s = filePtr.readline()
        if not s=="":
            s = s[3:]
            s = s.split()
            if s[0].isdigit():
                print("O")
                lines.append(s)
            elif s[0] in {"+", "-"}:
                print("U")
                lines.append(s)
        else:
            print("none")
            break
    filePtr.seek(ptr, 0);    #I did this to restore file pointer, so other functions accessing this file later don't misbehave
    return lines

和我正在使用的2个可能的main() - (请原谅我对python的无知) -

with open("./testStage1.txt", 'r') as osrc:
    osrc.seek(291, 0)
    L = makeLineList( osrc, osrc.tell())
    print "".join(L)

和另一个 -

osrc = open("./testStage1.txt", 'r')
osrc.seek(291, 0)
L = makeLineList( osrc, osrc.tell())
print "".join(L)
osrc.close()

终端上的输出都是令人失望的none

请注意以上代码是重现问题所需的最低要求,而不是整个代码。

修改 基于@ avenet的建议,我用google搜索&尝试在我的代码中使用iter(__next__ obj.next()在python 3.3+或next(obj) 2.7)但问题仍然存在,即使我调用{{1},我也无法读取下一行从函数内部查看这两个片段

  • version2接下来仅用于main() - ish部分transform_line函数未被调用。调用next()3次会在
  • 中产生期望/预期的输出
  • version3我的列表索引超出范围错误,即使对于肯定有数字的列表[0]

编辑2:我在next(osrc)的函数中尝试了scope check,并在下一行中使用了正确的缩进if not osrc in locals():。输出为print("osrc not reachable")。我也尝试从临时tLib.py中使用osrc not reachable,但结果相同。为什么osrc在这两种情况下都不可用?

编辑3:由于问题似乎是范围。 因此,为了避免传递文件变量,请创建一个唯一目的是读取一行的函数。获取下一行的决定取决于像isLineUseful()

这样的函数的返回值
from tLib import transform_line

尝试过,它在这个(notepad.cc/diniko93)示例testStage1.txt上完美运行。

所以我的编程问题得到了解决(感谢响应者:D)&我将此标记为已回答,但发布了有关def isLineUseful( text, lookFor ): if text.find(lookFor)!=-1: return 1 else: return 0 def makeList( pos, lookFor ): lines = [] with open("./testStage1.txt", 'r') as src: src.seek(pos) print(src.read(1)) while True: line = next(src) again = isLineUseful(line, lookFor) if again==0: src.seek(pos) break else: lines.append(line) return lines t = makeList(84, "+") print "\n".join(t) &的异常/行为的新问题。 readline()

P.S。我还在学习python的方法,所以如果你能建议更多 pythonic &我上面代码的 idomatic 版本。

3 个答案:

答案 0 :(得分:2)

首先,您没有使用Python,因为它应该被使用。使用像Python这样的语言的目的是编写更少的代码行来实现其他编程语言(如C ++或Java)中其他代码片段的相同结果。

没有必要将文件指针作为函数参数传递来读取文件,您可以直接打开传递文件名的函数中的文件。

然后,您可以使用文件名调用此函数,并将列表存储在最终将要操作的变量中。如果您不熟悉异常处理,可以使用模块os中的函数来检查文件是否已存在:os.path.exists(filename)

如果你想在你当前使用的行中搜索一个模式,你可以简单地使用一个if语句(有很多方法可以做到这一点,这只是一个例子):

if line not in list_of_strings_you_want_not_to_include: 
    lines.append(line)

如果要检查模式是否在开头,可以使用行上的startswith字符串函数:

if not str(line).startswith("+"):
    lines.append(line)     

如果您想跳过一定数量的字符,可以使用seek功能(正如您实际使用的那样)。这只是一种使用更多代码行的方式,但它仍然非常简单:

def read_file(filename, _from):
    lines = []
    try:
        with open(filename) as file:
            file.seek(_from)
            for line in file:
                lines.append(line)     
    except FileNotFoundError:
        print('file not found')
    return lines

filename = "file.txt"
lines = read_file(filename, 10)

更容易,您也可以这样做,而不是通过所有行显式迭代:

with open(filename) as file:
    file.seek(_from)
    return list(file)

或使用您最喜欢的功能readlines

with open(filename) as file:
    file.seek(_from)
    return file.readlines()

通过所有行显式迭代的目的和优点是,您可以在正确阅读的时刻使用行或字符进行大量检查和任何您想要的内容,因此我会采用我建议的第一个选项上方。

答案 1 :(得分:1)

如果您想以自己的方式修改线条:

def transform_line(line):
    if line != "":
        if line[0].isdigit():
            print("O")
        elif line[0] in {"+", "-"}:
            print("U")
    else:
        print("None")
    return line

with open("./testStage1.txt", 'r') as osrc:
    osrc.seek(291)
    lines = [transform_line(line) for line in osrc]
    #Do whatever you need with your line list

如果您不想变换线条,请执行以下操作:

with open("./testStage1.txt", 'r') as osrc:
    osrc.seek(291)
    lines = list(osrc)
    #Do whatever you need with your line list

如果你需要在某种条件下停止,或者只是实现一个行迭代器:

def line_iterator(file):
    for line in file:
        if not line[0].isdigit() and not line in ["+", "-"]:
            yield line
        else:
            break

with open("./testStage1.txt", 'r') as osrc:
    osrc.seek(291)
    lines = list(line_iterator(osrc))
    #To skip lines from the list containing 'blah'
    lines = [x for x in lines if 'blah' not in line]
    #Do whatever you need with your line list

答案 2 :(得分:0)

您尝试处理此输入:

<P> unnecessart line </P>
<P> Following is an example of list </P>
<P> 1. abc </P>
<P>     + cba </P>
<P>     + cba </P>
<P>             + xyz </P>

现在在你的大脑中,你只看到了重要的部分,但Python看到了一切。对于Python(以及任何其他编程语言),每行以<开头。这就是if永远不匹配的原因。

如果您删除<P>,请务必删除空格,因为

1. abc
    + cba

第二行以空格开头,因此s[0]不是+。要删除空格,请使用s.trim()