Pergunta

Existe alguma maneira de fazer uma função (os que eu estou pensando são no estilo dos mais simples que eu fiz que geram a seqüência Fibonnacci de 0 a um ponto, e todos os números primos entre dois pontos) funcionar indefinidamente. Por exemplo. até eu pressionar uma determinada tecla ou até que um tempo se passou, e não até que um número atinge um certo ponto?

Além disso, se ele é baseado no tempo, então existe alguma maneira eu poderia simplesmente estender o tempo e iniciá-lo indo a partir desse ponto, novamente, em vez de ter de recomeçar do 0? Estou ciente de que existe um módulo de tempo, eu só não sei muito sobre isso.

Foi útil?

Solução

A maneira mais simples é apenas para escrever um programa com um loop infinito, e depois bateu control-C para pará-lo. Sem mais descrição é difícil saber se isso funciona para você.

Se você fazê-lo com base no tempo, você não precisa de um gerador. Você pode apenas ter que fazer uma pausa para entrada do usuário, algo como um "Continuar? [Y / n]", leia de stdin, e dependendo do que você se quer sair do loop ou não.

Outras dicas

Você pode usar um gerador para isso:

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

Se você quiser alterar a condição de saída que você poderia passar um valor de volta para a função de gerador e usar esse valor para determinar quando sair.

Como em quase todas as línguas:

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

A segunda parte da sua pergunta é mais interessante:

Além disso, se ele é baseado no tempo, então há de qualquer maneira eu poderia simplesmente estender o tempo e iniciá-lo indo a partir desse ponto novamente em vez de ter que começar de novo a partir de 0

Você pode usar um yield vez de return na nextValue() função

Se você usar um segmento de criança para executar a função, enquanto os principais thread espera para entrada de caracteres ele deve funcionar. Basta lembrar de ter algo que interrompe o segmento infantil (no exemplo abaixo da runthread global)

Por exemplo:

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

faz exatamente isso

Se você realmente quer a função de correr e ainda quer a entrada do usuário (ou sistema), você tem duas soluções:

  1. multi-thread
  2. multi-processo

Ele vai depender de como multar a interação. Se você quiser apenas para interromper a função e não se preocupam com a saída, em seguida, multi-processo está bem.

Em ambos os casos, você pode contar com alguns recursos partilhados (arquivo ou memória compartilhada para multi-thread, variável com mutex associado para multi-thread) e verificar o estado desse recurso regularmente em sua função. Se for configurado para dizer-lhe para parar de fumar, apenas fazê-lo.

Exemplo de multi-thread:

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

Se você quiser sair com base no tempo, você pode usar o alarme do módulo de sinal (tempo) função, e as capturas a SIGALRM - aqui está um exemplo http://docs.python.org/library/signal.html#example

Você pode permitir que o usuário interrompa o programa de uma forma sã pela captura KeyboardInterrupt. Simplesmente capturar a exceção KeyboardInterrupt de fora você loop principal, e fazer qualquer limpeza você quer.

Se você quiser continuar mais tarde onde você parou, você terá que adicionar um pouco de persistência tipo. Eu picles uma estrutura de dados para o disco, que você pode ler de volta para continuar as operações.

Eu não tentei nada parecido com isso, mas você pode olhar em usar algo como memoizing , e cache para o disco.

Você poderia fazer algo assim para gerar números Fibonnacci durante 1 segundo depois parar.

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

Eu não tenho certeza quão eficiente ele é chamar time.time () em cada loop -. Dependendo do que você está fazendo dentro do loop, pode acabar tendo uma grande parte do desempenho afastado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top