Python - 在不使用循环/函数的情况下打印值

时间:2013-02-11 13:01:40

标签: python search recursion python-2.7 interrupt-handling

在Windows 7上使用Python 2.7。

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

我的问题:
在长时间搜索期间,我希望在retval上看到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)

3 个答案:

答案 0 :(得分:2)

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

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

你可以测试一下,虽然我不太确定它是如何处理循环内部的那样。

答案 1 :(得分:1)

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

答案 2 :(得分: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)