tgindex

Библиотека Python разработчика | Книги по питону

описание

Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq

18 166
подписчиков

Лучшие посты

за три месяца
  • 17 июл.1 230 просмотров7 реакций4 пересылок

    Почему range() в Python использует полуоткрытые интервалы? Функция range() в Python работает с полуоткрытыми интервалами. Например, range(2, 10) задаёт числа в диапазоне [2, 10), то есть [2, 3, 4, 5, 6, 7, 8, 9]. На первый взгляд это может показаться неочевидным или асимметричным, но у такого подхода есть свои преимущества. Почему полуоткрытые интервалы? Полуоткрытые интервалы позволяют легко "склеивать" смежные диапазоны без риска ошибок на единицу: - Если a = 2, b = 5, и c = 10, то [a, c) можно выразить как: [a, c) = [a, b) + [b, c) Это работает идеально, потому что конец одного интервала (`b`) автоматически становится началом следующего. В случае закрытых интервалов, такая "склейка" требует дополнительной обработки: [a, c] = [a, b] + [b+1, c] Связь с индексацией с нуля Индексация с нуля в Python также связана с этим принципом. Рассмотрим диапазон range(0, N): - Этот диапазон включает ровно N элементов, что делает код более предсказуемым: for i in range(0, N): print(i) Здесь i проходит значения от 0 до N-1, что логично и удобно. Преимущества для работы с массивами Полуоткрытые интервалы идеально подходят для работы с индексами массивов: arr = [10, 20, 30, 40, 50] print(arr[1:3]) # [20, 30] Интервал [1:3) охватывает элементы с индексами 1 и 2, но не 3, что упрощает вычисления границ. Исторический контекст Этот подход имеет глубокие корни в компьютерной науке. Эдсгер Дейкстра, один из пионеров программирования, в 1982 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными. 📲 Мы в MAX 👉@BookPython

  • 31 июл.1 214 просмотров3 реакций2 пересылок

    Когда вы создаете кастомный метод __repr__ для объекта, обычно нужно включить представление его атрибутов. Однако важно помнить, что нужно явно вызывать repr(), так как форматирование вызывает str() вместо repr(). Пример простого кода: class Pair: def __init__(self, left, right): self.left = left self.right = right def __repr__(self): class_name = type(self).__name__ repr_left = repr(self.left) repr_right = repr(self.right) return f'{class_name}({repr_left}, {repr_right})' Проблема возникает, если вы вызываете repr для объекта, который содержит ссылку на самого себя. Это может привести к рекурсии: In : p = Pair(1, 2) In : p Out: Pair(1, 2) In : p.right = p In : p Out: [...] RecursionError: maximum recursion depth exceeded while calling a Python object Для решения этой проблемы можно использовать декоратор reprlib.recursive_repr, который обрабатывает рекурсивные вызовы: @reprlib.recursive_repr() def __repr__(self): class_name = type(self).__name__ repr_left = repr(self.left) repr_right = repr(self.right) return f'{class_name}({repr_left}, {repr_right})' Теперь код работает корректно: In : p = Pair(1, 2) In : p.right = p In : p Out: Pair(1, ...) 📲 Мы в MAX 👉@BookPython

  • 19 июл.1 210 просмотров7 реакций2 пересылок

    Когда вам нужно очистить список в Python, вы, скорее всего, используете lst = []. Однако на самом деле вы просто создаёте новый пустой список и присваиваете его переменной lst, а все другие переменные, которые ссылаются на исходный список, продолжают хранить его содержимое. Пример: lst = [1, 2, 3] lst2 = lst lst = [] print(lst2) # [1, 2, 3] Хотя это кажется очевидным, правильное решение стало доступно только с введением метода lst.clear() в Python 3.3. До этого для очистки списка приходилось использовать: - del lst[:], или - lst[:] = []. Оба варианта работают, поскольку срезы позволяют модифицировать часть списка. Если вы берёте срез [:], он охватывает весь список. Теперь же lst.clear() является более читаемым и современным решением. 📲 Мы в MAX 👉@BookPython

  • 30 июл.1 208 просмотров6 реакций6 пересылок

    В Python блок else можно использовать не только после if, но и после циклов for и while. Код внутри else выполняется только в том случае, если цикл завершился естественным образом, то есть не был прерван с помощью break. Наиболее распространённый случай использования этого — поиск элемента в цикле с прерыванием через break, если элемент найден: # Пример 1: Список содержит нечётное число first_odd = None for x in [2, 3, 4, 5]: if x % 2 == 1: # Проверяем, является ли число нечётным first_odd = x break # Прерываем цикл, так как элемент найден else: raise ValueError('No odd elements in list') # Выполнится, если цикл завершился без break print(first_odd) # Результат: 3 Если в списке нет подходящего элемента, цикл завершается естественным образом, и выполняется блок else: # Пример 2: Список не содержит нечётных чисел for x in [2, 4, 6]: if x % 2 == 1: first_odd = x break else: raise ValueError('No odd elements in list') # Исключение будет поднято # ValueError: No odd elements in list 📲 Мы в MAX 👉@BookPython

  • 22 июл.1 192 просмотров6 реакций6 пересылок

    📌 О представлении данных в байтах в Python Когда мы храним данные в памяти или на устройстве хранения, их необходимо представить в виде байтов. Python позволяет работать с абстракцией данных, не задумываясь об их байтовом представлении. Однако при записи строки в файл мы фактически работаем с физической структурой данных. Чтобы записать символы в файл, их нужно преобразовать в байты — это называется кодированием (encoding). Когда вы читаете байты из файла и хотите преобразовать их в понятные символы, этот процесс называется декодированием (decoding). 🔤 Кодировки и их применение Существует множество методов кодирования. Один из самых популярных — Unicode, но сам по себе Unicode не является кодировкой в традиционном смысле. Unicode определяет соответствие между символами и их числовыми кодами. Например, 🐍 имеет код 128 013. Однако, чтобы записать числа в файл, нужна настоящая кодировка. Unicode обычно используется с utf-8, которая (в большинстве случаев) является кодировкой по умолчанию в Python. При чтении из файла Python автоматически декодирует данные, используя utf-8. Если вы хотите использовать другую кодировку, просто укажите её с помощью параметра encoding= в функции open. А чтобы работать с "чистыми" байтами, добавьте символ b к режиму открытия файла. Пример: # Кодирование строки в файл with open('example.txt', 'w', encoding='utf-8') as f: f.write('Привет, мир!') # Чтение в байтовом режиме with open('example.txt', 'rb') as f: data = f.read() print(data) # Вывод: b'\xd0\x9f\xd1\x80\xd0\xb8...' 📲 Мы в MAX 👉@BookPython

  • 28 июл.1 191 просмотров5 реакций3 пересылок

    Функция itertools.chain позволяет объединить несколько итерируемых объектов, чтобы работать с ними, как с единым целым: from itertools import chain print(list(chain(['a', 'b'], range(3), set('xyz')))) # Вывод: ['a', 'b', 0, 1, 2, 'x', 'z', 'y'] Иногда нужно проверить, пуст ли генератор (точнее, исчерпан ли он). Для этого можно попытаться получить следующий элемент с помощью next(). Если элемент есть, его нужно вернуть обратно в генератор, но сделать это напрямую невозможно. Однако можно «приклеить» его обратно с помощью chain: from itertools import chain def sum_of_odd(gen): try: first = next(gen) # Пытаемся получить первый элемент except StopIteration: raise ValueError('Empty generator') # Если генератор пуст, выбрасываем исключение # Используем chain для возврата первого элемента и объединения с остальными return sum( x for x in chain([first], gen) if x % 2 == 1 # Суммируем только нечетные числа ) Пример использования: print(sum_of_odd(x for x in range(1, 6))) # Вывод: 9 (1 + 3 + 5) print(sum_of_odd(x for x in range(2, 3))) # Вывод: 0 (нет нечетных чисел) print(sum_of_odd(x for x in range(2, 2))) # ValueError: Empty generator 📲 Мы в MAX 👉@BookPython

  • 20 июл.1 141 просмотров7 реакций9 пересылок

    Как ускорить вычисления в Python с помощью multiprocessing.Pool Когда речь заходит о ресурсоемких задачах, которые нагружают ваш CPU, стоит обратить внимание на библиотеку multiprocessing, а именно на класс Pool. Он позволяет задействовать все доступные ядра процессора, автоматически распределяя задачи между ними. Вот простой пример: import math from multiprocessing import Pool # Генерируем список входных данных inputs = [i ** 2 for i in range(100, 130)] # Функция для вычислений def f(x): return len(str(math.factorial(x))) # Последовательное выполнение %timeit [f(x) for x in inputs] # Результат: ~1.44 сек # Параллельное выполнение p = Pool(4) # Создаем пул из 4 процессов %timeit p.map(f, inputs) # Результат: ~451 мс 📲 Мы в MAX 👉@BookPython

  • 23 июл.1 116 просмотров3 реакций2 пересылок

    🔑 Использование объектов в качестве ключей словаря в Python В Python вы можете использовать любой объект в качестве ключа словаря, если он реализует метод __hash__. Этот метод возвращает целое число, но при этом важно соблюдать одно ключевое требование: равные объекты должны иметь одинаковый хэш (обратное утверждение необязательно). 👉 Не используйте изменяемые объекты в качестве ключей! Если объект изменяется после добавления в словарь, он становится "невидимым" для поиска, так как его хэш может измениться. 🌀 Странность с отрицательными хэшами Есть интересная особенность, которая может вас удивить при отладке или написании юнит-тестов. Рассмотрим следующий пример: class A: def __init__(self, x): self.x = x def __hash__(self): return self.x Результаты хэширования экземпляров класса: >>> hash(A(2)) 2 >>> hash(A(1)) 1 >>> hash(A(0)) 0 >>> hash(A(-1)) # внимание! -2 >>> hash(A(-2)) -2 💡 В CPython значение -1 зарезервировано для внутренних ошибок. Если хэш-значение равно -1, интерпретатор автоматически преобразует его в -2. Это может вызывать неожиданные проблемы при сравнении или использовании объектов в качестве ключей. 📲 Мы в MAX 👉@BookPython

  • 27 июл.1 097 просмотров8 реакций5 пересылок

    Метод format в Python для строк — мощный инструмент, поддерживающий множество возможностей, о которых вы, возможно, даже не знали. Каждый заменяемый плейсхолдер ({...}) может содержать три части: имя поля, преобразование и спецификацию формата. Имя поля используется для указания, какой именно аргумент должен быть подставлен: >>> '{}'.format(42) '42' >>> '{1}'.format(1, 2) '2' >>> '{y}'.format(x=1, y=2) '2' Преобразование позволяет указать, что вместо str() следует использовать repr() (или ascii()) при преобразовании объектов в строки: >>> '{!r}'.format(datetime.now()) 'datetime.datetime(2018, 5, 3, 23, 48, 49, 157037)' >>> '{}'.format(datetime.now()) '2018-05-03 23:49:01.060852' Спецификация формата задаёт, как значения будут представлены: >>> '{:+,}'.format(1234567) '+1,234,567' >>> '{:>19}'.format(1234567) ' 1234567' Эта спецификация может быть применена и к отдельному объекту с помощью функции format (не метода str): >>> format(5000000, '+,') '+5,000,000' Функция format вызывает метод __format__ объекта, поэтому вы можете изменить его поведение для своих типов. 📲 Мы в MAX 👉@BookPython

  • 21 июл.1 097 просмотров6 реакций5 пересылок

    Модуль multiprocessing в Python: потоки против процессов Модуль multiprocessing позволяет создавать не только процессы, но и потоки. Однако стоит помнить о главной особенности CPython — GIL (Global Interpreter Lock). Этот механизм блокирует выполнение байт-кода Python несколькими потоками одновременно. Это означает, что потоки полезны в основном в случаях, когда программа выполняет операции, не связанные с Python-интерпретатором, например, ожидание ввода-вывода (IO). К примеру, загрузка трёх различных статей из Википедии будет одинаково эффективной как с потоками, так и с процессами. Причём результат в три раза быстрее по сравнению с выполнением задачи в одном процессе: from multiprocessing import Pool from multiprocessing.pool import ThreadPool import requests def download_wiki_article(article): url = 'http://de.wikipedia.org/wiki/' return requests.get(url + article) process_pool = Pool(3) thread_pool = ThreadPool(3) thread_pool.map(download_wiki_article, ['a', 'b', 'c']) # ~376 ms process_pool.map(download_wiki_article, ['a', 'b', 'c']) # ~373 ms [download_wiki_article(a) for a in ['a', 'b', 'c']] # ~1.09 s Однако использование потоков для задач, нагружающих CPU, практически бессмысленно: import math from multiprocessing import Pool from multiprocessing.pool import ThreadPool def f(x): return len(str(math.factorial(x))) process_pool = Pool(4) thread_pool = ThreadPool(4) inputs = [i ** 2 for i in range(100, 130)] [f(x) for x in inputs] # ~1.48 s thread_pool.map(f, inputs) # ~1.48 s process_pool.map(f, inputs) # ~478 ms При задачах, требующих интенсивных вычислений, использование процессов вместо потоков даст значительный прирост производительности благодаря распределению нагрузки между несколькими ядрами процессора. 📲 Мы в MAX 👉@BookPython

  • 3 авг.1 029 просмотров2 реакций4 пересылок

    Тесты могут требовать временные файлы или директории. Для этого отлично подойдет модуль tempfile. Так как временные файлы обычно нужно удалять после использования, tempfile предоставляет как контекстный менеджер, так и простые функции: import os import tempfile with tempfile.TemporaryDirectory() as dir_path: open(os.path.join(dir_path, 'a'), 'w').close() open(os.path.join(dir_path, 'b'), 'w').close() open(os.path.join(dir_path, 'c'), 'w').close() assert files_of(dir_path) == ['a', 'b', 'c'] 📲 Мы в MAX 👉@BookPython

  • 25 июл.987 просмотров

    🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. https://max.ru/tipsysdmin Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП

  • 4 авг.956 просмотров4 реакций5 пересылок

    UTF-8 - это кодировка с переменной длиной. Один символ может быть закодирован с использованием одного, двух, трёх или четырёх байтов. Это означает, что нельзя начать чтение строки в кодировке UTF-8 с произвольного байта, так как это может случайно разрушить символ: In : lion = 'Löwe' In : lion.encode('utf-8')[2:] Out: b'\xb6we' In : lion.encode('utf-8')[2:].decode('utf-8') ... UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte Также это означает, что для пропуска первых N символов строки их необходимо прочитать и декодировать. Рассчитать смещение заранее невозможно. Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8: 0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Как видно, байт является начальным байтом символа, если его вид не совпадает с 10xxxxxx. Такие байты называются продолжением символа (continuation bytes). Давайте пропустим их: def cut_bytes(s, n): result = s.encode('utf-8')[n:] mask = int('11000000', 2) conbyte = int('10000000', 2) while result[0] and result[0] & mask == conbyte: result = result[1:] return result.decode('utf-8') Пример использования: In : cut_bytes(lion, 2) Out: 'we' In : cut_bytes(lion, 1) Out: 'öwe' 📲 Мы в MAX 👉@BookPython

  • 5 авг.946 просмотров4 реакций5 пересылок

    Иногда вам нужно запустить блок кода с несколькими контекстными менеджерами. Например: with open('f') as f: with open('g') as g: with open('h') as h: pass Начиная с Python 2.7 и 3.1, это можно сделать с помощью одного выражения with: o = open with o('f') as f, o('g') as g, o('h') as h: pass До этого можно было использовать функцию contextlib.nested: with nested(o('f'), o('g'), o('h')) as (f, g, h): pass Однако в современных версиях Python эта функция устарела и вызывает предупреждение. Вместо неё рекомендуется использовать более продвинутый инструмент — contextlib.ExitStack. Он позволяет войти в любое количество контекстов в произвольное время, но гарантирует их корректное завершение: from contextlib import ExitStack with ExitStack() as stack: f = stack.enter_context(o('f')) g = stack.enter_context(o('g')) other = [ stack.enter_context(o(filename)) for filename in filenames ] Это особенно полезно, когда количество контекстных менеджеров неизвестно заранее. 📲 Мы в MAX 👉@BookPython

  • 6 авг.871 просмотров3 реакций5 пересылок

    Рассмотрим следующую иерархию классов: class GrandParent: pass class Parent1(GrandParent): pass class Parent2(GrandParent): pass class Child(Parent1, Parent2): pass В каком порядке будет производиться поиск метода Child.x()? Наивный подход заключается в рекурсивном поиске через все родительские классы, что даст порядок: Child, Parent1, GrandParent, Parent2. Такой метод используется во многих языках программирования, однако он не совсем логичен, так как Parent2 более специфичен, чем GrandParent, и его нужно проверять раньше. Чтобы исправить эту проблему, Python использует линеаризацию C3 (C3 superclass linearization), алгоритм, который всегда ищет метод сначала во всех дочерних классах, а затем уже в родительских. Пример вывода MRO (Method Resolution Order): In : Child.__mro__ Out: (__main__.Child, __main__.Parent1, __main__.Parent2, __main__.GrandParent, object) 📲 Мы в MAX 👉@BookPython

  • 10 авг.810 просмотров4 реакций3 пересылок

    С версии Python 3.0 выбрасывание исключения внутри блока except автоматически добавляет перехваченное исключение в атрибут __context__ нового исключения. Это приводит к тому, что оба исключения отображаются в traceback: try: 1 / 0 except ZeroDivisionError: raise ValueError('Zero!') Результат выполнения: Traceback (most recent call last): File "test.py", line 2, in <module> 1 / 0 ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): File "test.py", line 4, in <module> raise ValueError('Zero!') ValueError: Zero! Вы также можете добавить __cause__ к любому исключению с помощью выражения raise ... from: division_error = None try: 1 / 0 except ZeroDivisionError as e: division_error = e raise ValueError('Zero!') from division_error Результат выполнения: Traceback (most recent call last): File "test.py", line 4, in <module> 1 / 0 ZeroDivisionError: division by zero The above exception was the direct cause of the following exception: Traceback (most recent call last): File "test.py", line 8, in <module> raise ValueError('Zero!') from division_error ValueError: Zero! 📲 Мы в MAX 👉@BookPython

  • 9 авг.802 просмотров7 реакций5 пересылок

    Прямой доступ к атрибутам объекта может быть не самой лучшей идеей. Если клиенты взаимодействуют с объектом через методы, вы всегда можете изменить способ обработки каждого запроса, в то время как при прямом доступе к атрибутам это может быть невозможно. Разные языки решают эту проблему по-разному. В Ruby синтаксически невозможно получить прямой доступ к атрибуту: obj.x — это вызов метода x. В Java рекомендуется делать все атрибуты приватными и писать тривиальные геттеры, например: public int getX() { return this.x; }. Python предлагает решение, которое в некотором роде похоже на то, что есть в Ruby. Вы можете определить свойство (property), чтобы obj.x вызывал метод вместо прямого возврата атрибута x. class Example: def __init__(self, x): self._x = x @property def x(self): return self._x 📲 Мы в MAX 👉@BookPython

  • 8 авг.727 просмотров2 реакций1 пересылок

    🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. https://max.ru/tipsysdmin Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Городские📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП https://max.ru/channel_krasnodar_novosty Краснодар Новости https://max.ru/channel_novosibirsk_novosti Новосибирск https://max.ru/channel_samara_novosti Новости Самары https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга https://max.ru/channel_kazan_novosti Новости Казани https://max.ru/channel_omsk_novosti Новости Омска https://max.ru/channel_moskva_24 Москва 24

  • 12 авг.652 просмотров2 реакций1 пересылок

    One Day Offer для Python-разработчиков!💚 15 августа открываем двери в команду Agent Execution Framework ⚡️ Коллеги создают платформу для GenAI‑агентов в банке — делают так, чтобы ИИ реально работал в серьёзных финпроцессах: с безопасностью, нагрузкой и пользой. Чем предстоит заниматься: ✔️ развивать backend на Python ✔️ подключать LLM, инструменты, базы знаний и RAG ✔️ строить пайплайны оценки качества агентов ✔️ участвовать в архитектуре и ревью кода Встречаемся 15 августа онлайн. Регистрируйся по ссылке

  • 12 авг.632 просмотров3 реакций16 пересылок

    Профайлинг и Оптимизация Производительности Когда ваш код уже не просто работает, а должен летать, на первый план выходит умение профилировать и оптимизировать производительность. Для Python это не просто трюки, а глубокое понимание CPython и его инструментов. Шаг 1: Точное Измерение (Profiling) Прежде чем оптимизировать, мы должны знать, где именно тратятся ресурсы. Слепое улучшение кода — это путь к бессмысленным изменениям и появлению новых багов. - Модуль cProfile: Стандартный и самый надежный инструмент для нахождения горячих точек (hotspots) — функций, где тратится больше всего времени. Он показывает совокупное время (tottime) и общее время (cumtime) выполнения каждой функции, включая вызовы извне. import cProfile import re cProfile.run('re.compile("foo|bar")', filename='profile_data') # Анализируем результаты import pstats p = pstats.Stats('profile_data') p.sort_stats('cumulative').print_stats(10) - Line-by-line Profilers (line_profiler): Если cProfile показывает функцию, которая "тормозит", но вам нужно понять, какая именно строка внутри этой функции виновата, используйте внешние инструменты, такие как line_profiler. # Декоратор @profile над нужной функцией # Запуск: kernprof -l my_script.py # Анализ: python -m line_profiler my_script.py.lprof - Анализ Памяти (memory_profiler): Для задач, связанных с большими данными или длительными процессами, где утечки памяти или излишнее потребление критичны, используйте memory_profiler или pympler. Шаг 2: Реальная Оптимизация (Beyond Simple Fixes) Найдя узкое место, приступаем к устранению, используя знания об устройстве Python. 1. Уменьшение Накладных Расходов Интерпретатора (Interpreter Overhead) - Использование Встроенных Функций и Модулей C: Встроенные функции (например, sum, map, sorted) и функции из стандартной библиотеки, написанные на C (например, itertools, collections), работают значительно быстрее, чем их эквиваленты на чистом Python, поскольку избегают накладных расходов на GIL и байткод. - Пример: Используйте collections.deque вместо list для быстрого добавления/удаления с обоих концов. 2. Манипуляции с Данными NumPy/Pandas - Векторизация: Если вы работаете с числовыми данными, полностью переходите на NumPy и Pandas. Вместо циклов for в Python, обрабатывающих элементы по одному, используйте векторизованные операции. Это позволяет выполнять вычисления на уровне C/Fortran, эффективно используя процессор. 3. Параллелизм vs. Конкурентность - CPU-bound задачи (расчеты): Из-за GIL (Global Interpreter Lock) чистый Python не может эффективно использовать несколько ядер ЦП для одновременного выполнения кода на Python. Используйте модуль multiprocessing для распараллеливания задачи между процессами. - I/O-bound задачи (сеть, диск): Если код проводит много времени в ожидании (ввод-вывод), используйте конкурентность с помощью asyncio (асинхронный ввод-вывод) или threading. В этом случае GIL не мешает, так как Python "освобождает" его во время ожидания. 📲 Мы в MAX 👉@BookPython