LINUX.ORG.RU

[Python] таймер

 


0

2

Ситуация такая: периодически, а именно каждые 5 сек. нужно менять значение переменной-счетчика, а этот циклический процесс должен проходить в течении 30 секунд. Как это делают Ъ-хакеры?

★★★★★

если при этом чего то должно происходит параллельно запускаете отдельный поток и в нем ждете по 5 сек при помощи time.sleep()

Если не должно - просто ждете по 5 сек при помощи time.sleep()

если хотите извартиться можно например запустить отдельный процесс, к-й будет каждый 5 сек кидать сигнал;-)

AIv ★★★★★
()

Как-то так, с апгрейдом под свои нужды.

from time	import time

class MyCounter:
    def __init__(s, start, delta):
        s.__value = start
        s.__delta = delta
        s.__now   = time()

    def __call__(s):
        _dl = time() - s.__now

        if _dl > s.__delta:
             _inc = int(_dl / s.__delta)
             
             s.__value += _inc
             s.__now += _inc * s.__delta

        return s.__value

a = MyCounter(0, 5)

v = a()

# ... 

v = a()

или так

from time	import time

class MyCounter:
    def __init__(s, start, delta, duration):
        s.__value = start
        s.__delta = delta
        s.__duration = duration

    def __iter__(s):
        s.__now = time()
        s.__stop = s.__now + s.__duration

        return s

    def next(s): return s()

    def __call__(s):
        _now = time()

        if _now > s.__stop: raise StopIteration

        _dl = _now - s.__now

        if _dl > s.__delta:
             _inc = int(_dl / s.__delta)

             s.__value += _inc
             s.__now += _inc * s.__delta

        return s.__value

for val in MyCounter(0, 5, 30):
    # do my job

Потоки в питоне лучше вообще не трогай. Если нужно что-то фоновое, то лучше смотреть на signal.alarm() и SIGALARM

mashina ★★★★★
()
Ответ на: комментарий от mashina

Код ужасен, первый вариант вообще кошмар, никогда так не делай. Подчёркивания зачем? Особенно для локальных переменных.

Потоки в питоне лучше вообще не трогай

why? Неужели этот самый, GIL? :). Из минусов в данном случае это то что сигналы получает активный поток, но это обходится.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Ну вот меня чем то прельстил вариант с сигналами:)

pylin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Код ужасен, первый вариант вообще кошмар, никогда так не делай.

Да ты просто не шаришь :)

Подчёркивания зачем?

см. матчасть что это значит и зачем оно нужно. Для локальных просто так.

why? Неужели этот самый, GIL? :). Из минусов в данном случае это то что сигналы получает активный поток, но это обходится.

Почему, почему.. потому что они слишком убоги. И из-за GIL'а, и из-за сигналов. Обходится очень некрасивыми и геморными методами и в большинстве случаев пользы от них нет.

mashina ★★★★★
()
Ответ на: комментарий от mashina

см. матчасть что это значит и зачем оно нужно

я pep-8 знаю, а ты? :)

__double_leading_underscore: when naming a class attribute, invokes name
      mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

потому что они слишком убоги

окей, вот неубогие треды :)

from gevent import Greenlet as Thread

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Допустим, ответил на бесполезный в нашем топике вопрос 'что это делает технически'. Где ответ на вопрос из моего поста - 'зачем это нужно практически'? Там же где-то про всё написано.

окей, вот неубогие треды :)

from gevent import Greenlet as Thread

facepalm.jpeg. Ну что, ещё поговим о разнице между продвинутыми генераторами и потоками?

mashina ★★★★★
()
Ответ на: комментарий от true_admin

Мои оба примера прекрасны, спорить не буду ;) Первый это болванка, второй адаптированная болванка под возможные требования, которые в топике не описаны.

mashina ★★★★★
()
Ответ на: комментарий от mashina

У тебя в обоих примерах нету sleep или чего-то подобного. Этим мне и не нравится твои примеры т.к. их точность напрямую зависит от частоты вызова функций и лишние проверки это пустая трата проца. Вот :).

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

У тебя в обоих примерах нету sleep или чего-то подобного.

Где и как должен быть sleep() зависит от дальнейшего применения счётчика, потому его там и нет.

Этим мне и не нравится твои примеры т.к. их точность напрямую зависит от частоты вызова функций

Смотри лучше код, точность в указанных цифрах в топике (т.е. интервал 5 секунд в течении 30 сек) _не_ зависит от кол-ва вызовов, т.к. при любом кол-ве вызовов пересчёт всегда идёт не более 5-6 раз. И это один из самых точных методов расчёта счётчика. Даже если использовать сигналы и прочие таймеры, всё равно придётся делать именно так и никак иначе, если, конечно, нужна хоть какая-то точность.

mashina ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.