简体   繁体   English

readline函数返回空字符串

[英]readline function returning empty string

I am new to Python; 我是Python的新手。 little experience in programming C++. 很少有C ++编程经验。 I saw this question but it doesn't address my problem. 我看到了这个问题,但没有解决我的问题。

Python 2.7.9, 64-bit AMD, Windows 7 Ultimate, NTFS, administrator privileges & no "read only" attribute on file to be read. Python 2.7.9、64位AMD,Windows 7 Ultimate,NTFS,管理员特权以及要读取的文件上没有“只读”属性。

I want to create a list of strings which fulfill a certain criteria, the strings are lines of the file(see notepad.cc/diniko93).So I wrote the following function- 我想创建一个满足特定条件的字符串列表,这些字符串是文件的行(请参见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

and the 2 possible main()-like (pardon my ignorance of python) bodies that I am using are- 和我正在使用的2个可能的main()-like(原谅我对python的无知)是-

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

and the other one- 另一个-

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

both the times the output on terminal is a disappointing none 这两个时间上端子的输出是一个令人失望的none

Please Note that the code above is minimum required to reproduce the problem and not the entire code. 请注意 ,上面的代码是重现问题的最低要求,而不是完整的代码。

EDIT: Based on @avenet's suggestion, I googled & tried to use iter ( __next__ obj.next() in python 3.3+ or next(obj) in 2.7) in my code but the problem persists, I am unable to read next line even if I call next(osrc) from inside the function check out these 2 snippets 编辑:根据@ avenet的建议下,我用Google搜索和尝试(使用ITER __next__ obj.next()在python 3.3+或next(obj) 2.7)在我的代码,但问题仍然存在,我无法甚至阅读下一行如果我从函数内部调用next(osrc) ,请检查这2个代码段

  • version2 next used only in main()-ish part transform_line function is not called. 接下来仅在main()-ish部分中使用的version2不会调用transform_line函数。 Calling next() 3 times produces desirable/expected output but in 调用next()3次会产生期望的/预期的输出, 但是
  • version3 I get a list index out of range error, even for lists[0] which definately has a digit version3我得到列表索引超出范围错误,即使对于肯定有数字的list [0]

EDIT 2: I tried scope check inside my functions as if not osrc in locals(): and in next line with proper indent print("osrc not reachable") . 编辑2:我尝试在我的函数内部进行范围检查if not osrc in locals():并在下一行使用适当的缩进print("osrc not reachable") And the output is osrc not reachable . 并且输出osrc not reachable I also tried using from tLib import transform_line from a temporary tLib.py but with identical results. 我还尝试了from tLib import transform_line使用临时tLib.py中的from tLib import transform_line ,但结果相同。 Why is osrc not available in either case? 为什么在两种情况下osrc都不可用?

EDIT 3: Since the problem appears to be of scope. 编辑3:由于问题似乎是范围。 So to avoid passing of file variable- make a function whose sole purpose is to read a line. 因此,为避免传递文件变量,请创建一个函数的唯一目的是读取一行。 The decision to get next line or not depends upon returned value of a function like isLineUseful() 是否决定下一行取决于isLineUseful()之类的函数的返回值。

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)

Tried it, it works perfectly on this(notepad.cc/diniko93) sample testStage1.txt. 对其进行了尝试,使其在此(notepad.cc/diniko93)示例testStage1.txt上可以完美运行。

So my programming issue is solved (thanks to responders :D) & I am marking this as answered but posting a new question about the anomalous/ behavior of readline() & __next__ . 这样我的编程问题就解决了(感谢响应者:D),我将其标记为已回答,但发布了一个有关readline()__next__的异常/行为的新问题。

PS I am still learning the ways of python so I would be very happy if you could suggest a more pythonic & idomatic version of my code above. PS:我仍在学习python的方法,因此,如果您能为我的代码建议一个更pythonicidomatic的版本,我将非常高兴。

First of all, you are not using Python as it should be used. 首先,您没有使用Python,应该使用它。 The purpose of using a language like Python is to write just fewer lines of code to achieve the same result of other snippets of code in other programming languages, such as C++ or Java. 使用Python之类的语言的目的是编写更少的代码行,以达到其他编程语言(例如C ++或Java)的其他代码片段的相同结果。

It's not necessary to pass a file pointer as a function parameter to read the file, you can open directly the file within the function to which you pass the filename. 不必将文件指针作为函数参数来读取文件,您可以在传递文件名的函数中直接打开文件。

Then you can call this function with the file name and store the list in a variable that you will eventually manipulate. 然后,您可以使用文件名调用此函数,并将列表存储在最终将要操作的变量中。 If you are not familiar with exceptions handling, you could for example use a function from the module os to check if the file already exists: os.path.exists(filename) . 如果您不熟悉异常处理,则可以例如使用模块os的函数来检查文件是否已存在: os.path.exists(filename)

If you want to search for a pattern in the line you are currently using, you can simply use an if statement (there are a lot of ways of doing that, this is just an example): 如果要在当前使用的行中搜索模式,则可以简单地使用if语句(这样做的方法很多,这只是一个示例):

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

If you to check if the pattern is at the beginning, you can use the startswith string function on the line: 如果要检查模式是否在开头,则可以在该行上使用startswith字符串函数:

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

If you want to skip a certain amount of characters, you can use the seek function (as you are effectively using). 如果要跳过一定数量的字符,可以使用seek功能(因为您正在有效使用)。 This is just a way that uses more lines of code, but it's still very simple: 这只是一种使用更多代码行的方法,但仍然非常简单:

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)

Much easier, you can also do this, instead of iterating explicitly through all lines: 更加容易,您也可以执行此操作,而不是通过所有行显式地进行迭代:

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

Or using your favourite function readlines : 或者使用您喜欢的函数readlines

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

The purpose and the advantage of iterating explicitly through all lines is that you can do a lot of checking and whatever you want with the lines or characters in the right moment you are reading, so I would adopt certainly the first option I suggested above. 在所有行中进行显式迭代的目的和优点是,您可以在阅读的正确时机进行大量检查,并根据需要对行或字符进行任何检查,因此,我肯定会采用上面建议的第一个选项。

If you want to modify the lines your way: 如果要按自己的方式修改行:

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

If you don't want to transform lines just do this: 如果您不想变换线条,请执行以下操作:

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

Or just implement a line iterator if you need to stop on a certain condition: 或者,如果您需要在特定条件下停止,则只需实施一个行迭代器:

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

You try to process this input: 您尝试处理此输入:

<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>

Now in your brain, you just see the important bits but Python sees everything. 现在,在大脑中,您只看到重要的部分,而Python则看到了所有内容。 For Python (and any other programming language), each line starts with < . 对于Python(和其他任何编程语言),每一行均以<开头。 That's why the if 's never match. 这就是if永不匹配的原因。

If you stripped the <P> , be sure to strip the spaces as well because 如果去除了<P> ,请确保也去除空格,因为

1. abc
    + cba

the second line starts with a space, so s[0] isn't + . 第二行以空格开头,因此s[0]不是+ To strip spaces, use s.trim() . 要删除空格,请使用s.trim()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM