如何计算发生异常的次数并打印出来?

How to count number of occurred exceptions and print it?

我想做点什么。例如我想打开多个文件并统计其中的字数,但我想知道有多少文件打不开。

这是我尝试过的:

i = 0
def word_count(file_name):
    try:
        with open(file_name) as f:
            content = f.read()
    except FileNotFoundError:
        pass
        i = 0
        i += 1
    else:
        words = content.split()
        word_count = len(words)
        print(f'file {file_name} has {word_count} words.')


file_name = ['data1.txt','a.txt','data2w.txt','b.txt','data3w.txt','data4w.txt']
for names in file_name:
    word_count(names)
print(len(file_name) - i , 'files weren\'t found')
print (i)

所以,我得到这个错误:

runfile('D:/~/my')
file data1.txt has 13 words.
file data2w.txt has 24 words.
file data3w.txt has 21 words.
file data4w.txt has 108 words.
Traceback (most recent call last):

  File "D:\~\my\readtrydeffunc.py", line 27, in <module>
    print(len(file_name) - i , 'files weren\'t found')

NameError: name 'i' is not defined

我也试过别的东西,但我想我不太理解作用域的含义。我认为是因为 i 被分配到 except 范围之外,但是当我在 except 范围内分配 i = 0 时,我最后无法打印它,因为它会在执行后被销毁.

是的,您走对了。您需要在函数外定义并递增 i,或者通过函数传递值,递增,并 return 新值。在函数外定义 i 更常见,也更符合 Pythonic。

def count_words(file_name):
    with open(file_name) as f:
        content = f.read()
    words = content.split()
    word_count = len(words)
    #print(f'file {file_name} has {word_count} words.')
    return word_count


file_name = ['data1.txt','a.txt','data2w.txt','b.txt','data3w.txt','data4w.txt']

i = 0
for names in file_name:
    try:
        result = count_words(names)
    except FileNotFoundError:
        i += 1

print(i, 'files weren\'t found')

我建议将其分解为 2 个函数;一个负责处理字数统计,另一个负责控制脚本的流程。控制者应该处理出现的任何错误以及处理和来自所述错误的反馈。

def word_count(file_name):
    with open(file_name) as f:
        content = f.read()
        words = content.split()
        word_count = len(words)
        print(f'file {file_name} has {word_count} words.')

def file_parser(files):
    i = 0
    for file in files:
        try:
            word_count(file)
        except FileNotFoundError:
            i+=1
    if i > 0:
        print(f'{i} files were not found')

file_names = ['data1.txt','a.txt','data2w.txt','b.txt','data3w.txt','data4w.txt']
file_parser(file_names)

虽然将代码重构为不使用 global variables 应该是首选方法(请参阅编辑以了解可能的重构),但获得代码 运行 的最小修改是删除 passi = 0except 子句中,并要求 i 在您的函数中全局使用:

def word_count(file_name):
    global i  # use a `i` variable defined globally
    try:
        with open(file_name) as f:
            content = f.read()
    except FileNotFoundError:
        i += 1  # increment `i` when the file is not found
    else:
        words = content.split()
        word_count = len(words)
        print(f'file {file_name} has {word_count} words.')


i = 0
file_name = ['data1.txt','a.txt','data2w.txt','b.txt','data3w.txt','data4w.txt']
for names in file_name:
    word_count(names)
print(i, 'files weren\'t found')

请注意 i 将包含未找到的文件数。


编辑

经过合理重构的代码可能类似于:

def word_count(filepath):
    result = 0
    with open(filepath) as file_obj:
        for line in file_obj:
            result += len(line.split())
    return result


def process_files(filepaths):
    result = {}
    num_missing = 0
    for filepath in filepaths:
        try:
            num_words = word_count(filepath)
        except FileNotFoundError:
            num_missing += 1
        else:
            result[filepath] = num_words
    return result, num_missing


filenames = [
    'data1.txt', 'a.txt', 'data2w.txt', 'b.txt', 'data3w.txt', 'data4w.txt']
wordcounts, num_missing = process_files(filenames)
for filepath, num_words in wordcounts.items():
    print(f'File {filepath} has {num_words} words.')
print(f'{i} files weren\'t found')

备注:

  • word_count() 函数现在只做一件事:字数统计。这是逐行完成的,以更好地处理可能很长的文件,如果一次加载这些文件可能会填满内存。
  • process_files() 函数提取基本信息并将它们存储在 dict
  • 所有结果的打印都在一个地方完成,并且可以很容易地包含在一个 main() 函数中。
  • num_missing(以前是 i,大约)现在是局部变量。

最后请注意,虽然显式计算异常数量是一种方式,另一种方式是通过从输入文件路径的数量中减去 result 中的元素数量来获取此信息。 这可以在任何地方完成,在 process_files().

中没有必要这样做