0

在 Windows 7 上使用 Python 2.7。

我有一个递归函数,可以在路径中查找文件,也可以在子文件夹中查找。

我的问题:
在长时间搜索期间,我希望看到retvalon的值KeyboardInterrupt
但是代码在 上引发错误KeyboardInterrupt,因为它中断了“更深”的函数调用/运行。

我的问题:
有没有办法不中断循环,但仍然打印值,
或者
另一种方法来做同样的事情(不是使用KeyboardInterrupt而是其他的东西)

我的代码:

import os

def search(path,filename):
    try:
        global found
        folders = []
        retval = []

        try:    
            for item in os.listdir(path):
                if not os.path.isfile(os.path.join(path, item)):
                    folders.append(os.path.join(path, item))
                else:
                    if item == filename:
                        found += 1
                        retval.append(os.path.join(path, item))
        except WindowsError,e:
            print str(e)[10:]

        for folder in folders:
            retval += search(folder,filename)
        return retval
    except KeyboardInterrupt:
        print retval

found = 0
path = 'C:\\'
filename = 'test.txt'
print search(path,filename)
4

3 回答 3

2

您可以KeyboardInterrupt在层次结构中添加处理程序:

for folder in folders:
        try:
             retval += search(folder,filename)
        except KeyboardInterrupt:
               print retval
return retval

你可以测试一下,虽然我不太确定它是如何在你所拥有的循环中处理的。

于 2013-02-11T13:07:16.887 回答
1

你需要保留一个更全局的 retval 副本,我会使用函数的一个属性,并在你有一个适合你的 retval 时分配给它。

于 2013-02-11T13:08:55.597 回答
1

我不确定这如何或是否可以在 Windows 上工作,但在 unix 下,您可以执行以下操作:

import signal
import sys

count = 0

def handler(signum,frame):
    global count
    print "Value of 'i' is",i
    count += 1
    if count >= 2:
        sys.exit(0)

signal.signal(signal.SIGINT,handler)
i = 0
while True:
    i += 1

在这里,我在 ctrl-C 被捕获(两次)后退出程序,因为我没有任何其他退出程序的好方法。

此处使用全局数据仅用于演示目的——在野外,我会使用一个类并将实例方法传递给信号处理程序,以维护调用之间的状态。-- 例如,类似:

import signal

class Reporter(object):
    def __init__(self):
        self.retval = []

    def handler(self,signum,frame):
        print self.retval

r = Reporter()
signal.signal(signal.SIGINT,r.handler)

self.retval然后您可以在进入/退出函数时重新绑定:

import os

def search(path,filename):
    global found
    folders = []
    retval = []
    r.retval = retval #<--- Line added

    try:    
        for item in os.listdir(path):
            if not os.path.isfile(os.path.join(path, item)):
                folders.append(os.path.join(path, item))
            else:
                if item == filename:
                    found += 1
                    retval.append(os.path.join(path, item))
    except WindowsError,e:
        print str(e)[10:]

    for folder in folders:
        retval += search(folder,filename)
        r.retval = retval   #<---- Line added
    return retval

found = 0
path = 'C:\\'
filename = 'test.txt'
print search(path,filename)

我想我更喜欢使用非递归解决方案os.walk

import os

def search(path,filename):
    retval = []
    r.retval = retval

    for (dirpath, dirnames, filenames) in os.walk(path):
         retval.extend(os.path.join(path,dirpath,item) for item in filenames if item == filename)
    return retval

path = 'C:\\'
filename = 'test.txt'
print search(path,filename)
于 2013-02-11T13:18:26.577 回答