Python 如何计算发生的异常数并打印它?

Python 如何计算发生的异常数并打印它?,python,python-3.x,try-except,Python,Python 3.x,Try Except,我想做点什么。例如,我想打开多个文件并计算其中的单词,但我想知道有多少文件无法打开 这就是我所尝试的: 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:

我想做点什么。例如,我想打开多个文件并计算其中的单词,但我想知道有多少文件无法打开

这就是我所尝试的:

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')
文件data1.txt有13个字。
文件data2w.txt有24个字。
文件data3w.txt有21个字。
文件data4w.txt有108个字。
回溯(最近一次呼叫最后一次):
文件“D:\~\my\readtrydeffunc.py”,第27行,在
打印(len(文件名)-i,“未找到文件”)
名称错误:未定义名称“i”

我还尝试了其他方法,但我想我不太理解范围的含义。我想这是因为
I
被分配到了except范围之外,但是当我在
except
范围内分配
I=0
时,我不能在最后打印它,因为它在执行后会被销毁。

是的,你走对了。您需要在函数外部定义并递增i,或者通过函数传递值,递增并返回新值。在函数外定义i更常见,也更像python

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

我建议将其分为两个功能;一个用于处理字数计算,另一个用于控制脚本流。控制者应处理出现的任何错误,以及处理和反馈上述错误

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)

虽然将代码重构为不使用应该是首选方法(有关可能的重构,请参见编辑),但使代码运行的最小修改是删除
pass
i=0
中的
except
子句,并要求在函数中全局使用
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\u count()
    函数现在只做一件事:单词计数。这是逐行执行的,以便更好地处理可能很长的文件,如果一次加载,这些文件可能会填满内存
  • process_files()
    函数提取基本信息并将其存储在
    dict
  • 所有结果的打印都在一个地方完成,可以很容易地包装在
    main()
    函数中
  • num\u missing
    (以前的
    i
    ,circa)现在是一个局部变量
最后请注意,虽然显式计算异常数是一种方法,但另一种方法只是通过从输入文件路径数中减去
result
中的元素数来获取此信息。
这可以在任何地方进行,无需在
process\u files()

中进行此操作。您是否尝试过删除Exception中的
i=0
?您知道
全局
关键字的作用吗?这是否回答了您的问题?为什么这里首选全局变量?根据我的经验,它们是尽可能避免的。例如,请参见,注意不要像在
word\u count
中那样对函数及其返回值使用相同的名称。此外,此代码并没有真正实现确定确实存在的文件的字数的初衷,因为最终循环中的
result
在每次迭代中都会被覆盖,然后才被使用(打印或以其他方式使用)。我相信您可以在except语句中执行任何操作,但它只会在引发异常时触发。此外,如果该操作引发新的异常,您将使程序崩溃。将此重构为函数绝对是一个好主意。一个不太好的方法是在
word\u count()
中为函数及其变量之一使用相同的名称。此外,如果函数返回计算结果,而不是打印结果,那么代码将更干净。打印是有用的,但会使函数变得不那么有用(例如,如果要进行进一步的计算或使用不同的UI)。因此,最好在函数的主要目的之外执行此操作。