fazendo um programa executado indefinidamente em python
-
06-07-2019 - |
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.
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:
- multi-thread
- 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