【问题标题】:Cannot call a function twice, Python [duplicate]不能两次调用函数,Python [重复]
【发布时间】:2018-07-19 02:04:07
【问题描述】:

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

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。

我是编码新手,所以我不知道为什么会发生这种情况以及如何解决它。请帮忙。

【问题讨论】:

  • 打开和关闭文件inside函数。
  • 第一个副本几乎以比其他副本更明显的方式与您的问题完全匹配;第二个有最好的答案。因此,我只是将两者以及该问题的“规范”版本列表中的其他内容都加入了。如果您立即弄清楚如何修复代码以及为什么要修复,不要觉得您必须阅读所有四页上的所有文本;他们只是在那里,以防有人需要他们。

标签: python


【解决方案1】:

那是因为循环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(也适用于非常大的文件,但我不喜欢它):

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

【讨论】:

  • 选项3a...把seek(0)放在函数的开头...
  • @juandavidposada 尽管我的回答解决了您问题中的问题,但您的功能实际上并没有按照您所描述的那样做:计算不包含 @987654331 中任何字符的英文单词@字符串。
  • @AGNGazer 谢谢!至于功能,我已经修好了。根据我自己的反复试验观察,它现在似乎正在发挥作用。
猜你喜欢
  • 2019-07-24
  • 2017-10-28
  • 1970-01-01
  • 2022-11-15
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
  • 1970-01-01
相关资源
最近更新 更多