【问题标题】:readline function returning empty stringreadline 函数返回空字符串
【发布时间】:2014-12-30 13:42:45
【问题描述】:

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

Python 2.7.9、64 位 AMD、Windows 7 Ultimate、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

我正在使用的两个可能的 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 的建议,我用谷歌搜索并尝试在我的代码中使用 iter(__next__obj.next() 在 python 3.3+ 或 next(obj) 在 2.7),但问题仍然存在,即使我打电话也无法阅读下一行next(osrc) 从函数内部检查这 2 个 sn-ps

  • version2 next 仅用于 main()-ish 部分 transform_line 函数未被调用。调用 next() 3 次会产生理想/预期的输出
  • version3 我得到一个 list index out of range 错误,即使是 list[0] 肯定有一个数字

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

编辑 3: 因为问题似乎是范围。 因此,为了避免传递文件变量 - 创建一个函数,其唯一目的是读取一行。是否获取下一行的决定取决于 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)

试过了,它在这个(notepad.cc/diniko93)样本testStage1.txt上完美运行。

所以我的编程问题得到了解决(感谢响应者:D),我将其标记为已回答,但发布了一个关于 readline()__next__ 的异常/行为的新问题。

附:我还在学习 python 的方法,所以如果你能建议我上面代码的更多 pythonicidomatic 版本,我会很高兴。

【问题讨论】:

  • 另外,在 Python 中,您不需要分号来结束语句,除非您想将两条语句放在一行中,而且您几乎不想这样做。
  • 那么显而易见的情况如何:文件中没有行以数字或+- 开头,而none 是由readline() 在EOF 上返回空字符串引起的?
  • else 部分是否不匹配?
  • notepad.cc 页面似乎是空白的。
  • 所有行都以“

    ”开头。 “strip,对吧?你确定你用对了吗?请记住,如果您不分配结果,则仅调用 strip 不会执行任何操作。 s.strip("<P>") 没有效果,你必须做s = s.strip("<P>")

标签: python readline


【解决方案1】:

首先,您没有使用 Python,因为它应该被使用。使用 Python 之类的语言的目的是编写更少的代码行,以达到与其他编程语言(例如 C++ 或 Java)中其他 sn-ps 代码相同的结果。

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

然后您可以使用文件名调用此函数并将列表存储在您最终将操作的变量中。如果您不熟悉异常处理,例如可以使用模块 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()

显式遍历所有行的目的和优势在于,您可以在阅读的正确时刻对行或字符进行大量检查和任何您想要的操作,所以我肯定会采用我建议的第一个选项以上。

【讨论】:

  • 好的,但是从 OP 的 osrc.seek(291, 0); 行来看,他似乎想跳过前 291 个字符。如果他以这种方式遍历文件的行,他应该怎么做?
  • 我传递了指针,因为我在程序中使用了不同的 functions.py 文件。我import pyFunctions
  • 恕我直言readlines() 会比按照您的第一个代码 sn-p 建议的那样读取列表中的所有行要好得多。
  • @newPython 没必要,你只需要传递文件名
  • @newPython 为什么好多了?
【解决方案2】:

如果你想按照自己的方式修改行:

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

【讨论】:

  • 好的,但是从 OP 的 osrc.seek(291, 0); 行来看,他似乎想跳过前 291 个字符。如果他以这种方式遍历文件的行,他应该怎么做?
  • 让我们实现一个迭代器,我的朋友!!
  • @avenet 我听从了您的建议 - 请查看有问题的 Edit 并告诉我有什么问题。 . .
  • @newPython 我的解决方案给你一个列表吗?正如我在您的编辑中看到的那样,您正在尝试使用下一个,下一个仅适用于可迭代元素,在列表上它不起作用。
  • @newPython 在 lines 变量上创建的列表已经为您提供了过滤后的数据。你还需要什么?
【解决方案3】:

您尝试处理此输入:

<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(和任何其他编程语言),每一行都以 &lt; 开头。这就是if 永远不会匹配的原因。

如果你去掉了&lt;P&gt;,一定要去掉空格,因为

1. abc
    + cba

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-02
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多