1

有什么方法可以制作一个函数(我正在考虑的那些是我制作的简单函数的样式,它生成从 0 到一个点的斐波那契序列,以及两点之间的所有素数)无限期运行。例如,直到我按下某个键或直到某个时间过去,而不是直到某个数字达到某个点?

另外,如果它是基于时间的,那么有什么办法可以延长时间并再次从该点开始,而不必从 0 开始?我知道有一个时间模块,我只是不太了解它。

4

7 回答 7

2

最简单的方法就是编写一个无限循环的程序,然后按 control-C 停止它。如果没有更多描述,很难知道这是否适合您。

如果您基于时间进行操作,则不需要生成器。你可以让它暂停用户输入,比如“继续?[y/n]”,从标准输入读取,取决于你得到什么退出循环。

于 2008-11-04T16:58:14.257 回答
2

如果你真的希望你的函数运行并且仍然需要用户(或系统)输入,你有两种解决方案:

  1. 多线程
  2. 多进程

这将取决于交互的精细程度。如果你只是想中断函数而不关心退出,那么多进程就可以了。

在这两种情况下,您都可以依赖一些共享资源(多线程的文件或共享内存,多线程的具有关联互斥锁的变量)并在您的函数中定期检查该资源的状态。如果它被设置为告诉你退出,那就去做吧。

多线程示例:

from threading import Thread, Lock
from time import sleep

class MyFct(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.mutex = Lock()
        self._quit = False

    def stopped(self):
        self.mutex.acquire()
        val = self._quit
        self.mutex.release()
        return val

    def stop(self):
        self.mutex.acquire()
        self._quit = True
        self.mutex.release()

    def run(self):
        i = 1
        j = 1
        print i
        print j
        while True:
            if self.stopped():
                return
            i,j = j,i+j
            print j

def main_fct():
    t = MyFct()
    t.start()
    sleep(1)
    t.stop()
    t.join()
    print "Exited"

if __name__ == "__main__":
    main_fct()
于 2008-11-04T17:10:49.223 回答
2

您可以为此使用生成器:

def finished():
    "Define your exit condition here"
    return ...

def count(i=0):
    while not finished():
        yield i
        i += 1

for i in count():
    print i

如果要更改退出条件,可以将一个值传回生成器函数并使用该值来确定何时退出。

于 2008-11-05T08:33:49.017 回答
1

与几乎所有语言一样:

while True:
  # check what you want and eventually break
  print nextValue()

你问题的第二部分更有趣:

另外,如果它是基于时间的,那么无论如何我都可以延长时间并再次从该点开始,而不必从 0 重新开始

您可以在函数中使用 ayield而不是returnnextValue()

于 2008-11-04T16:55:50.953 回答
1

如果在主线程等待字符输入时使用子线程运行该函数,它应该可以工作。只要记住有一些东西可以停止子线程(在下面的全局运行线程示例中)

例如:

import threading, time
runthread = 1
def myfun():
   while runthread:
      print "A"
      time.sleep(.1)

t = threading.Thread(target=myfun)
t.start()
raw_input("")
runthread = 0
t.join()

就是这样做的

于 2008-11-04T17:04:28.830 回答
0

如果要根据时间退出,可以使用信号模块的 alarm(time) 函数,并捕获 SIGALRM - 这是一个示例http://docs.python.org/library/signal.html#example

您可以通过捕获 KeyboardInterrupt 让用户以理智的方式中断程序。只需从主循环外部捕获 KeyboardInterrupt 异常,然后进行任何您想要的清理。

如果您想稍后从中断的地方继续,则必须添加某种持久性。我会将数据结构腌制到磁盘,您可以读回以继续操作。

我没有尝试过这样的事情,但是您可以考虑使用诸如memoizing之类的东西,并缓存到磁盘。

于 2008-11-04T18:29:31.373 回答
0

你可以做这样的事情来生成斐波那契数 1 秒然后停止。

fibonnacci = [1,1]
stoptime = time.time() + 1 # set stop time to 1 second in the future
while time.time() < stoptime:
  fibonnacci.append(fibonnacci[-1]+fibonnacci[-2])

print "Generated %s numbers, the last one was %s." % (len(fibonnacci),fibonnacci[-1])

我不确定在每个循环中调用 time.time() 的效率如何——取决于你在循环中所做的事情,它最终可能会降低很多性能。

于 2008-11-04T23:27:14.750 回答