2010-08-03 36 views
92

Có cách nào, ví dụ, in Hello World! cứ sau mỗi giây? Ví dụ, chương trình sẽ đi qua bất kỳ mã nào tôi đã có, sau đó một khi nó đã được 5 giây (với time.sleep()) nó sẽ thực thi mã đó. Tôi sẽ sử dụng điều này để cập nhật một tập tin mặc dù, không in Hello World.Chạy mã nhất định cứ sau n giây

Ví dụ:

startrepeat("print('Hello World')", .01) # Repeats print('Hello World') ever .01 seconds 

for i in range(5): 
    print(i) 

>> Hello World! 
>> 0 
>> 1 
>> 2 
>> Hello World! 
>> 3 
>> Hello World! 
>> 4 
+6

Liên quan: [Cách tốt nhất để lặp lại thực hiện hàm mỗi x giây bằng Python là gì?] (Http://stackoverflow.com/q/474528/4279) – jfs

Trả lời

205
import threading 

def printit(): 
    threading.Timer(5.0, printit).start() 
    print "Hello, World!" 

printit() 

# continue with the rest of your code 
+3

Điều này không có tác dụng - nó sẽ chỉ in thế giới hello sau đó làm bất cứ mã nào tôi đặt sau nó, mà không lặp lại chính nó. –

+0

bạn có thể có thể tạo ra một phương pháp SetAlarm mà mất tất cả các đối số yêu cầu để thực hiện các chức năng và phương pháp này sẽ thiết lập luồng.Timer và chỉ trở lại, tôi có nghĩa là như thế này .......... timer = threading.Timer (chờ đợi, fn, args, kwargs) bạn cũng có thể sử dụng mx DateTime để tính toán khoảng thời gian bằng cách sử dụng DateTime.RelativeDateTime (days = interval), timer.start() – shahjapan

+2

@Zonda, oops, quên bắt đầu luồng - chỉnh sửa ngay bây giờ để sửa chữa, xin lỗi. –

17
def update(): 
    import time 
    while True: 
     print 'Hello World!' 
     time.sleep(5) 

Điều đó sẽ chạy như một hàm. Các while True: làm cho nó chạy mãi mãi. Bạn luôn có thể lấy nó ra khỏi chức năng nếu bạn cần.

+1

Không hoạt động; nó chỉ chạy mãi mãi và tôi không thể làm bất cứ điều gì khác trong khi nó được. –

+0

Bạn muốn làm những việc gì khác cùng một lúc? –

+12

Vâng, điều này chỉ chạy trong một vòng lặp. Bạn đã không xác định trong câu hỏi rằng bạn sẽ làm một cái gì đó khác trong khi chờ đợi vì vậy tôi giả định đó là những gì bạn cần. – avacariu

1

Bạn có thể bắt đầu một chuỗi riêng biệt có nhiệm vụ duy nhất là đếm trong 5 giây, cập nhật tệp, lặp lại. Bạn sẽ không muốn chuỗi riêng biệt này can thiệp vào chuỗi chính của bạn.

79

tôi mất khiêm tốn về đề tài này, một sự tổng quát của câu trả lời Alex Martelli, với start() và stop() kiểm soát:

from threading import Timer 

class RepeatedTimer(object): 
    def __init__(self, interval, function, *args, **kwargs): 
     self._timer  = None 
     self.interval = interval 
     self.function = function 
     self.args  = args 
     self.kwargs  = kwargs 
     self.is_running = False 
     self.start() 

    def _run(self): 
     self.is_running = False 
     self.start() 
     self.function(*self.args, **self.kwargs) 

    def start(self): 
     if not self.is_running: 
      self._timer = Timer(self.interval, self._run) 
      self._timer.start() 
      self.is_running = True 

    def stop(self): 
     self._timer.cancel() 
     self.is_running = False 

Cách sử dụng:

from time import sleep 

def hello(name): 
    print "Hello %s!" % name 

print "starting..." 
rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start() 
try: 
    sleep(5) # your long-running job goes here... 
finally: 
    rt.stop() # better in a try/finally block to make sure the program ends! 

Các tính năng:

  • Chỉ thư viện chuẩn, không bị giảm bên ngoài dencies
  • start()stop() được an toàn để gọi nhiều lần ngay cả khi bộ đếm thời gian đã bắt đầu/dừng
  • chức năng được gọi là có thể có đối số vị trí và đặt tên
  • Bạn có thể thay đổi interval bất cứ lúc nào, nó sẽ có hiệu lực sau tiếp theo chạy. Tương tự cho args, kwargs và thậm chí function!
+0

đẹp! sử dụng nó. – Wapiti

+0

Tất cả những gì tôi cần là hàm 'sleep()'. Cảm ơn bạn. –

+0

@JossieCalderon: Hàm 'sleep()' nằm trong mô-đun 'time' từ Thư viện chuẩn của Python, không cần bất kỳ mã bổ sung nào để sử dụng nó ngoài' import'. Nhưng xin lưu ý đây là cuộc gọi chặn một lần, không phải là bộ hẹn giờ đa luồng lặp lại theo yêu cầu của OP. Về cơ bản, 'sleep()' chỉ là một tạm dừng, không phải là một bộ đếm thời gian. – MestreLion

23

Lưu cho mình một tập tâm thần phân liệt và sử dụng lịch trình nâng cao Python: http://pythonhosted.org/APScheduler

Mã này là đơn giản như vậy:

from apscheduler.scheduler import Scheduler 

sched = Scheduler() 
sched.start() 

def some_job(): 
    print "Every 10 seconds" 

sched.add_interval_job(some_job, seconds = 10) 

.... 
sched.shutdown() 
+2

Trước hết, submodule được gọi là 'schedulers', với 's'. Và không có lớp Scheduler trong đó. Có lẽ BackgroundScheduler? Dù sao, câu trả lời này là không đầy đủ và không hoạt động. –

+2

Đã lâu rồi, tôi đoán tôi đã dán mã từ hướng dẫn sử dụng web. Đoạn mã trên bây giờ đã được sửa chữa (vẫn chưa được kiểm tra, nhưng nó xuất phát từ mã làm việc của riêng tôi và tôi đang sử dụng nó liên tục). PS: có lẽ chúng tôi đang xem xét các phiên bản/mô-đun khác nhau? Tôi chắc chắn dòng của tôi là "từ apscheduler.scheduler nhập khẩu Scheduler" với vốn S và không số nhiều. –

+2

@ MadsSkjern: Tôi thấy rằng [chi nhánh 2.1 có mô-đun 'apscheduler.scheduler' (không có' s')] (https://bitbucket.org/agronholm/apscheduler/src/11c5c1e7b8c33205293168e044d90b7f2c84a21b/apscheduler/?at=2.1). Nhánh 3 hiện tại thì không. – jfs

4

Dưới đây là một phiên bản mà không tạo ra một chủ đề mới mỗi n giây:

from threading import Event, Thread 

def call_repeatedly(interval, func, *args): 
    stopped = Event() 
    def loop(): 
     while not stopped.wait(interval): # the first call is in `interval` secs 
      func(*args) 
    Thread(target=loop).start()  
    return stopped.set 

Sự kiện được sử dụng để dừng lần thứ e lặp đi lặp lại:

cancel_future_calls = call_repeatedly(5, print, "Hello, World") 
# do something else here... 
cancel_future_calls() # stop future calls 

Xem Improve current implementation of a setInterval python

+0

Cần lưu ý rằng mặc dù điều này cho phép một số thứ khác chạy trong khi chờ đợi 'func' chạy lại, giải pháp này không tài khoản phải mất bao lâu 'func' để chạy. Vì vậy, giải pháp này chờ đợi 'n' giây * giữa * chạy, thay vì chạy mỗi' n' giây. Các giải pháp khác ở trên ít nhất là đến gần hơn để chạy mỗi 'n' giây, mặc dù giải pháp này có lợi thế của nó quá. – Mike

+0

@Mike: yes. Nếu bạn theo liên kết; bạn thấy rằng nó được đề cập một cách rõ ràng và giải pháp tương ứng được đề xuất. Nó phụ thuộc vào một trường hợp cụ thể những gì giải pháp là thích hợp hơn. – jfs

8

Đây là một ví dụ đơn giản tương thích với APScheduler 3.00+:

# note that there are many other schedulers available 
from apscheduler.schedulers.background import BackgroundScheduler 

sched = BackgroundScheduler() 

def some_job(): 
    print('Every 10 seconds') 

# seconds can be replaced with minutes, hours, or days 
sched.add_job(some_job, 'interval', seconds=10) 
sched.start() 

... 

sched.shutdown() 

Ngoài ra, bạn có thể sử dụng như sau. Không giống như nhiều lựa chọn thay thế, bộ hẹn giờ này sẽ thực thi mã mong muốn cứ mỗi n giây chính xác (không phụ thuộc vào thời gian để mã thực thi). Vì vậy, đây là một lựa chọn tuyệt vời nếu bạn không có khả năng trôi dạt.

import time 
from threading import Event, Thread 

class RepeatedTimer: 

    """Repeat `function` every `interval` seconds.""" 

    def __init__(self, interval, function, *args, **kwargs): 
     self.interval = interval 
     self.function = function 
     self.args = args 
     self.kwargs = kwargs 
     self.start = time.time() 
     self.event = Event() 
     self.thread = Thread(target=self._target) 
     self.thread.start() 

    def _target(self): 
     while not self.event.wait(self._time): 
      self.function(*self.args, **self.kwargs) 

    @property 
    def _time(self): 
     return self.interval - ((time.time() - self.start) % self.interval) 

    def stop(self): 
     self.event.set() 
     self.thread.join() 


# start timer 
timer = RepeatedTimer(10, print, 'Hello world') 

# stop timer 
timer.stop() 
Các vấn đề liên quan