Python无法两次调用函数

时间:2018-07-19 02:04:07

标签: python

我尝试编写一个函数,该函数接受一个字符串,并返回英语中不包含该字符串中任何字符的单词数。

op= open('words.txt')

def avoids(forbidden):
    """counts the number of words in Enlgish which do not contain any
    character found in forbidden str"""
    number=0
    for line in op:
        count=0
        for letter in line.strip():
            if forbidden.count(letter)==0:
                count=count+1
        if count==len(line.strip()):
            number=number+1
    return number

print(avoids('e'))

print(avoids('a'))

运行程序时,print(avoids('e'))运行正常,打印37641;但是,print(avoids('a'))会显示0。无论我在函数调用中作为参数放入什么字符串,第一个函数始终返回正确的值,而第二个函数始终返回0。

我是编码的新手,所以我不知道为什么会这样以及如何解决。请帮助。

1 个答案:

答案 0 :(得分:3)

这是因为for line in op:循环结束后,文件已读到末尾,不再需要读取任何内容。

有几种选择:

选项1(更糟)::重新打开文件:

with open('words.txt') as op:
    print(avoids('e'))

with open('words.txt') as op:
    print(avoids('a'))

选项2(更好)::读取所有行并将其传递给avoids()

def avoids(forbidden, lines):
    """counts the number of words in Enlgish which do not contain any
    character found in forbidden str"""
    number=0
    for line in lines:
        count=0
        for letter in line.strip():
            if forbidden.count(letter)==0:
                count=count+1
        if count==len(line.strip()):
            number=number+1
    return number

with open('words.txt') as op:
    lines = op.readlines()
    print(avoids('e', lines))
    print(avoids('a', lines))

但是,这要求将所有行都保留在内存中,这对于较小的文件是可以的,但是对于非常大的文件可能是个问题。

选项3a (对于大文件来说更好):

这与选项1相同,但是在函数内部放置了open()

def avoids(forbidden, filename):
    """counts the number of words in Enlgish which do not contain any
    character found in forbidden str"""
    number=0
    with open(filename) as op:
        for line in op:
            count=0
            for letter in line.strip():
                if forbidden.count(letter)==0:
                    count=count+1
            if count==len(line.strip()):
                number=number+1
    return number

print(avoids('e', 'words.txt'))
print(avoids('a', 'words.txt'))

选项3b (也适用于非常大的文件,但我不喜欢它):

op.seek(0)之前添加return number。或者,(可能更好),如@kindall在注释中提到的,可以将op.seek(0)放在函数的开头,以确保我们在开始读取行之前位于文件的开头。这会将文件“倒带”到开头,并且只允许在函数外部打开一次文件。从本质上讲,这将使您的旧功能按预期工作。