Search
Write a publication
Pull to refresh
@resetmeread⁠-⁠only

Скромный пастух нулей и единиц…

Send message

В первую очередь Django, потом Flask, а потом хоть что из этого списка. Знание внутренностей Django очень пригодится в дальнейшей работе.

Судя по тексту, у автора все тезисы в выводах точно были равны нулю и он выбрал вполне правильный путь саморазвития, что достойно уважения.

По собственному опыту скажу, джуньоры своеобразно понимают «стремится к нулю». Скорее как «не равна нулю» и начинают кидать резюме с целью «а вдруг прокатит». Из них 90% даже не владеет минимум знаний для начала работы, а это легко вскрывается на собеседовании, но это уже бесполезная трата времени и денег компании.
Выводы верные, но я бы заменил «стремится к нулю» на просто «равна нулю». Так будет правдивее.

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

Я уж думал опять нерабочий синхронный велосипед для асинхронной задачи, а оказалось используется сторонний сервис. Это неспортивно

Какие-то фантастические агитаторы поработали? Или просто подвезли 10 автобусов людей и заставили голосовать?

Хотелось бы увидеть в статье не догадки, а факты.

Крымчане особо не расстроились. У них есть солнце, море и горы. А с парашютом можно прыгнуть и без компьютера.

Вы все же некорректно измеряете. Вам функция возвращает время выполнения цикла 100000 итераций. Во время выполнения на машине могут произойти прерывания и интрепретатор Python может получить меньший квант времени, а это скажется на времени исполнения этого цикла.

Если запускать timeit из командной строки, то выводится лучшее время из 3 запусков цикла. Это позволяет нивелировать прерывания во время исполнения, так как лучшее время исполнения даст та итерация во время которой произойдет наименьшее количество прерываний.

Обпатите внимание на это предложение в документации docs.python.org/3/library/timeit.html
Note however that timeit() will automatically determine the number of repetitions only when the command-line interface is used.

Другая проблема в самом декораторе. По сути он замалчивает исключения по таймауту и исключения от асинхронной очереди. Что в корне неправильно. Они должны быть обработаны и желательно не в декораторе, а в коде метода или функции. Иначе ваш декоратор может привести к ситуации когда замолченное исключение будет годами прятать баг. Лучше не замалчивать, а дать упасть приложению, а по трейсбеку найти проблему и пофиксить.

Сейчас в мире Python получилось так что мы имеем два Python: один асинхронный, а другой синхронный. Они в принципе разные и лучше код для разных питонов держать отдельно. Иначе выходят вот такие библиотеки, которые позволяют любым путем, но выполнить функцию будь она асинхронная или синхронная: github.com/miyakogi/syncer/blob/master/syncer.py

Да и просто расставив sync/await не получить правильно работающий асинхронный код. Если убрать асинхронность из декоратора, то вообщем ничего не изменится для вызываемого под ним метода или функции. По существу обработка исключений — это не IO bound задача для которой придумали асинхронность, поэтому нет смысла обрабатывать исключения асинхронно, так как в момент обработки может прилететь какое-то совсем другое исключение и совсем из другого места кода.

Для обучения это декоратор хороший пример и мне понравился Ваш подход к постоянному улучшению. Да и обе статьи получились интересные.

Небольшой прирост будет:
$ python3 -m timeit -s 'from test1 import divide_decorator' 'divide_decorator(1,0)'                       
1000000 loops, best of 3: 1.07 usec per loop
$ python3 -m timeit -s 'from test1 import divide_partial' 'divide_partial(1,0)'                           
1000000 loops, best of 3: 0.993 usec per loop

Только вызов как-то вот так нужно сделать:
    def __call__(self, func):
        if iscoroutinefunction(func):
            return partial(self._coroutine_exception_handler, func)
        return partial(self._sync_exception_handler, func)

    def _sync_exception_handler(self, func, *args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            return self.handlers.get(e.__class__, Exception)(e)

Получается так чем больше аргументов в partial передаешь, там больше выигрыш.
self как бы вмораживается в вызов и на него не таратится время на его передачу в стек, а вся машинерия на С, от суда есть прирост но незначительный. А лучше вообще не вызывать, как в соседней ветку.

Странно вы все же измеряете. Вот так у меня:
$ python3 -m timeit -s 'from test import math_with_try' 'math_with_try.divide(1,0)'
1000000 loops, best of 3: 0.415 usec per loop
$ python3 -m timeit -s 'from test import math_with_decorator' 'math_with_decorator.divide(1,0)'
1000000 loops, best of 3: 1.08 usec per loop
$ python3 -m timeit -s 'from test import math_with_partial' 'math_with_partial.divide(1,0)'
1000000 loops, best of 3: 0.998 usec per loop
А метод разве не функция которой передается self первым параметром?
Еще нолик добавьте к количеству лупов. В примере маловато для быстрых машин. Еще может быть Python не собран с С модулем functools, а в коде есть файлбэк на питоновскую версию. Пропробуйте симортировать модуль _functools. Если импортируется, то все ОК.

В новых питонах еще есть partialmethod, но идея такая же.
Еще можно слегка ускорить используя partial:
from functools import partial
...
    def __call__(self, func):
        self.func = func

        if iscoroutinefunction(self.func):
            return partial(self._coroutine_exception_handler, self)
        return partial(self._sync_exception_handler, self)
...
В этом случае процесс был более-менее отлажен, этого человека просто терпели, так как понимали что если уволят, то его работа ляжет на плечи других, а нового программиста вводить в курс дела это месяца на 2-3 растянется.

В нормальной команде никто не будет обсуждать длину строки. Есть более важные темы для обсуждения, а 80 символов всех устраивает.
Умеющий писать код в 80 символов строки легко уместит и в 99.

Я помню случай, когда один программист попросил сделать в команде 100 длину строки, через неделю он уже попросил 120, а еще через неделю и этого стало мало. Он давал названия функций в 86 символов, а перевод строки вообще не считал нужным делать. При этом он считал себя чертовки хорошим программистом.

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

Вообще при работе с профессиональными и сильными разработчиками никогда не встает вопрос о том какую длину строки выбрать в команде. Все легко умещают в 80 строк.

Если бы было так, тот PEP-8 бы объявили устаревшим и выпустили новый.


Источник изложил свое субъективное мнение, а мое субъективное мнение в том что надо выгонять из команд людей не умеющих писать читаемый код в 80 символов. Больше 80 символов — это проявление неуважения к коллегам.


И конечно же трехколоночный мердж с длиной в 120 эта адская боль. Кто мерджил, тот поймет.

айти-Маяковский всегда должен укладывается в 80 символов в строке… А то в печать не примут.
Батарею не заметил что сильно жрать стала. Все в пределах нормы.
Спасибо, за подсказки. Так и сделал. Откатываюсь.
И так уже делал. Результат тот-же. Скачивает и пытается установить, а потом пишет что не может установить.

На чистую MacOS ставиться без проблем. Что-то мешает ей обновиться.

Решил откатиться полностью на 10.14, а жаль.

Information

Rating
Does not participate
Registered
Activity