问题
I facing a problem. I found a solution I'm explaining below but I want some advice aout to right way to resolve it.
Here is the problem:
I have a class object called Item. This Item has a method, call make_request which makes a GET request on a server, and save the result. Now, I have implemented 3 Item object which calls make_request. The Item objects gonna call the method each 3 minutes, but these make_requests must be delayed by 1 minutes from the previous object's call.
Example :
- 14:00 - Item0.make_request
- 14:01 - Item1.make_request
- 14:02 - Item2.make_request
- 14:03 - Item0.make_request
- 14:04 - Item1.make_request
- 14:05 - Item2.make_request
- 14:06 - Item0.make_request
- 14:07 - Item1.make_request
- 14:08 - Item2.make_request
- 14:09 - Item0.make_request
- 14:10 - Item1.make_request
- 14:11 - Item2.make_request
- 14:12 - Item0.make_request
- 14:13 - Item1.make_request
- 14:14 - Item2.make_request ... etc
What I do actully is a while loop where I check the time minute and call the right object's method.
from datetime import datetime
Item0 = Item(name="Item0")
Item1 = Item(name="Item1")
Item2 = Item(name="Item2")
while True:
if str(datetime.now().time.minute[-1]) in ['0', '3', '6']:
Item0.make_request()
if str(datetime.now().time.minute[-1]) in ['1', '4', '7']:
Item1.make_request()
if str(datetime.now().time.minute[-1]) in ['2', '5', '8']:
Item2.make_request()
This is a solution, but it's not clean and I don't like it. It is also missing 1 minute. I was thinking about using Queue.
I'm waiting for your advice :)
EDIT : something more robust
Thank a lot for your answers. I found a good solution for the first problem.
Now, I'm asking myself if I can, in the same context, use a Queue. The idea is to call the make_request independently of the result of the previous make_request.
For example: At 14:00:00 I call Item0.make_request. Unfortunately, it takes more than 60 seconds to get the result of Item0.make_request but I want my Item1.make_request to be called independently at 14:01:00.
It happens sometimes
回答1:
Usually, when you have a number of items, on which the same thing is to be done, it is best to keep them in a list:
items = [Item(name="Item0"), Item(name="Item1"), Item(name="Item2")]
Then, no special logic is needed to see which the current minute is. Just run them sequentially with 1 minute delay:
while True:
for item in items:
item.make_request()
time.sleep(60) # 60 seconds
There is one drawback, about which you may or may not care: as it is, the time between two requests will be 60 seconds plus the time taken by make_request()
. There are ways to avoid that, but perhaps you don't care about such details.
回答2:
I came up with something overkill and configurable according to your need.
import time
# Assuming your class
class Item:
def __init__(self, name, number_of_ticks_to_act_in, *args, **kawrgs):
self.name = name
self.number_of_ticks_to_act_in = number_of_ticks_to_act_in
def make_request(self):
print(f"Making a requests from {self.name}")
# Item0 and Item1 will post every 2 mins and Item2 every 3 mins.
items = [Item("Item0", 2), Item("Item1", 2), Item("Item2", 3)]
# ?: Your configs
seconds_per_tick = 60 # Every tick can be in every 60 seconds or how you want it.
ticks_passed = 0 # This is a counter to keep track of ticks passed.
max_ticks_item = max(items, key=lambda i: i.number_of_ticks_to_act_in) # The counter gets set back to 0 once the max ticks that you stated have exceeded, this will let you run the code forever and never have to worry about the number surpassing int size. Overkill.
is_condition_met = True # You can set a condition to stop your forever while loop
while is_condition_met:
# The counter is reset if it exceeds your max ticks.
if ticks_passed >= max_ticks_item.number_of_ticks_to_act_in:
ticks_passed = 0
ticks_passed += 1
time.sleep(seconds_per_tick)
# Only Items with the same tick will get executed, this lets you have 2 or more Items of the same tick.
for item in filter(lambda x: ticks_passed % x.number_of_ticks_to_act_in == 0,
items):
item.make_request()
Hope this isn't too complicated. Added as much comments as I could.
来源:https://stackoverflow.com/questions/65738427/python-class-programming-and-queuing