Команда Python time.sleep в цикле с условием if / else - PullRequest
0 голосов
/ 06 мая 2018

У меня вопрос по команде time.sleep в цикле if/else. Я делаю запрос API для разных мест с широтой и долготой. В общем, мне нужен запрос на 5 лет. Я использую две for петли по широте и долготе и за запрошенные пять лет. Проблема в том, что я могу отправлять только 6 запросов в минуту. Из-за этого я использую команду time.sleep следующим образом:

 for lat, lon in zip(lats, lons):
     for year in years:
         args = {
             'interpolate': False,
             'lat': lat,
             'lon': lon,
             'date_from': year + '-01-01',
             'date_to': year + '-12-31',
             'capacity': 500,
             'height': 44,
             'turbine': 'Enercon E40 500',
             'format': 'json',
             'metadata': False,
             'raw': True,
         }
         r = s.get(url, params=args)
         data = pd.read_json(r.text, orient='index')
         df = df.append(data)
     time.sleep(61)

Функция работает хорошо и команда time.sleep тоже! Но в таком виде функция ждет 61 секунду после последнего прохождения. Я хочу сделать это чуть-чуть "более плавным" с помощью цикла if/else таким образом, если цикл использует последнюю широту / долготу, команду time.sleep можно игнорировать. Годы - это обычный список, а широта / долгота указаны в отдельной таблице Excel. У кого-нибудь есть идея, как я могу написать это? То, как я это попробовал, не работает, и мне нужно новое вдохновение ... Спасибо!

1 Ответ

0 голосов
/ 06 мая 2018

6 запросов в минуту не соответствуют 5 запросам на внутренний цикл, поэтому вам необходимо отделить режим ожидания от цикла. Вы не хотите беспричинного сна, когда оказывается, что вы находитесь в конце итерации и спите без веской причины. И вам не нужно жестко закодированное время сна, потому что оно не учитывает время, которое вы потратили на обработку.

Решение - написать класс, который будет отслеживать временные ограничения для вас. Он может запоминать время, и один раз каждые шесть раз, когда он вызывается, подождать время перепада между 60 секундами и тем временем, которое уже прошло.

Поместите кардиостимулятор в начало внутреннего цикла, и он будет спать один раз каждые 6 запросов, когда вы уже знаете, что ожидаете еще один запрос.

class Pacer:

    def __init__(self, burst_size, seconds):
        self.tick = time.time()
        self.burst_size = burst_size
        self.seconds = seconds
        self.count = 1

    def step(self):
        if self.count % self.seconds == 0:
            delta = self.seconds - (time.time() - self.tick)
            if delta > 0:
                time.sleep(delta)
            self.tick = time.time()
        self.count += 1

pacer = Pacer(6, 60)
for lat, lon in zip(lats, lons):
    for year in years:
        pacer.step()
        args = {
            'interpolate': False,
            'lat': lat,
            'lon': lon,
            'date_from': year + '-01-01',
            'date_to': year + '-12-31',
            'capacity': 500,
            'height': 44,
            'turbine': 'Enercon E40 500',
            'format': 'json',
            'metadata': False,
            'raw': True,
        }
        r = s.get(url, params=args)
        data = pd.read_json(r.text, orient='index')
        df = df.append(data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...