Python:类编程和队列

2024-09-30 18:17:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我面临一个问题。我找到了一个解决方案,我在下面解释,但我想得到一些正确解决方法的建议

问题出在这里:

我有一个名为的类对象。此有一个方法,调用发出请求,在服务器上发出获取请求,并保存结果。 现在,我已经实现了3个对象,它调用发出请求对象将每3分钟调用一次方法,但这些make_请求必须比上一个对象的调用延迟1分钟

例如:

  • 14:00-Item0.make_请求
  • 14:01-Item1.make_请求
  • 14:02-项目2.提出请求
  • 14:03-Item0.make_请求
  • 14:04-项目1.提出请求
  • 14:05-项目2.提出请求
  • 14:06-Item0.make_请求
  • 14:07-项目1.提出请求
  • 14:08-项目2.提出请求
  • 14:09-Item0.make_请求
  • 14:10-Item1.make_请求
  • 14:11-项目2.提出请求
  • 14:12-Item0.make_请求
  • 14:13-Item1.make_请求
  • 14:14-项2.提出请求 ... 等

实际上,我所做的是一个while循环,其中我检查时间分钟并调用正确对象的方法

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

这是一个解决方案,但它不干净,我不喜欢它。 它也少了1分钟。我在考虑使用队列

我在等你的建议:)

编辑:更健壮的东西

非常感谢你的回答。我找到了解决第一个问题的好办法

现在,我在问自己,在相同的上下文中,是否可以使用队列。 其思想是调用make_请求,独立于前一个make_请求的结果

例如: 14:00:00时,我呼叫Item0.make_请求。 不幸的是,获取Item0.make_request的结果需要60秒以上,但我希望在14:01:00独立调用我的Item1.make_request

这有时会发生


Tags: 项目对象方法namedatetimemakeiftime
2条回答

通常,当您有许多项目要做相同的事情时,最好将它们保存在列表中:

items = [Item(name="Item0"), Item(name="Item1"), Item(name="Item2")]

然后,不需要特殊的逻辑来查看当前分钟是哪一分钟。只需以1分钟的延迟顺序运行它们:

while True:
    for item in items:
        item.make_request()
        time.sleep(60)  # 60 seconds

有一个缺点,你可能会也可能不会在意:实际上,两个请求之间的时间是60秒加上make_request()所花费的时间。有很多方法可以避免这种情况,但也许你不在乎这些细节

我想出了一些可以根据你的需要进行配置的方法

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

希望这不是太复杂。添加尽可能多的评论

相关问题 更多 >