#python #codegems
Ключевое слово for работает с итерируемыми объектами. А ключевое слово await – с объектами, допускающими ожидание.
В настоящее время asyncio не предоставляет асинхронного API файловой системы – в отличие от Node.js.
Начиная с Python 3.9 сопрограмма asyncio.to_thread упрощает делегирование файлового ввода-вывода пулу потоков, предоставляемому библиотекой asyncio.
Под капотом цикл событий asyncio обращается к .send, чтобы привести в действие ваши сопрограммы, а ваши сопрограммы с помощью await вызывают другие сопрограммы, в т. ч. библиотечные. await заимствует большую часть реализации у предложения yield from, которое также обращается к .send для управления сопрограммами.
Цепочка await в конце концов достигает низкоуровневого объекта, допускающего ожидание, который возвращает генератор, к которому цикл событий может обращаться в ответ на такие события, как срабатывание таймера или сетевой ввод-вывод. Низкоуровневые объекты, допускающие ожидание, и генераторы в конце таких цепочек await находятся глубоко внутри библиотек, они не являются частью их API и могут быть расширениями, написанными на C.
Для достижения максимальной производительности при работе с asyncio мы должны заменить все функции, осуществляющие ввод-вывод, асинхронными версиями, которые активируются в результате выполнения await или asyncio.create_task, для того чтобы управление возвращалось циклу событий, пока функция ждет завершения ввода-вывода.
У asyncpg есть важное достоинство – он позволяет обойти отсутствие в PostgreSQL поддержки высокой конкурентности (в этой СУБД используется один серверный процесс на каждое подключение), поскольку реализует пул подключений для внутреннего подключения к самой Postgres.
Эдсгер Дейкстра изобрел семафор в начале 1960-х годов. Идея простая, но настолько гибкая, что большинство других объектов синхронизации, например блокировки и барьеры, можно построить на основе семафоров. В стандартной библиотеке Python есть три класса Semaphore: по одному в модулях threading,multiprocessing и asyncio.
В классе asyncio.Semaphore имеется внутренний счетчик, который уменьшается на 1 всякий раз, как выполняется await для метода-сопрограммы .acquire(), и увеличивается на 1 при вызове метода .release(), который не является сопрограммой, потому что никогда не блокирует выполнение. Начальное значение счетчика задается при создании объекта Semaphore:
Ожидание .acquire() не приводит к задержке, когда счетчик больше 0, но если счетчик равен 0, то .acquire() приостанавливает ожидающую сопрограмму до тех пор, пока какая-нибудь другая сопрограмма не вызовет .release() для того же семафора, увеличив тем самым счетчик. Вместо того чтобы обращаться к этим методам напрямую, безопаснее использовать semaphore как асинхронный контекстный менеджер:
Стоит написать первое async def, как в программе неизбежно будут появляться все новые и новые async def, await,
async with и async for. И внезапно использование неасинхронных библиотек становится проблемой.
Атрибуты-данные и методы в Python носят общее название «атрибуты»; метод – это просто вызываемый атрибут. Помимо атрибутов-данных и методов,мы можем создавать еще свойства, позволяющие заменить открытые атрибуты-данные методами-акцессорами (т. е. методами чтения и установки), не изменяя интерфейс класса.
Пользовательский класс, в котором имеется метод getattr, может реализовать вариант динамических атрибутов, который я называю виртуальными атрибутами; они не объявлены в исходном коде класса и отсутствуют в экземпляре dict, но могут быть получены из какого-то другого места или вычислены «на лету», когда программа пытается прочитать несуществующий атрибут, например obj.no_such_attr.
Функция keyword.iskeyword(…) позволяет проверить, является ли строка ключевым словом языка.
Ключевое слово for работает с итерируемыми объектами. А ключевое слово await – с объектами, допускающими ожидание.
В настоящее время asyncio не предоставляет асинхронного API файловой системы – в отличие от Node.js.
Начиная с Python 3.9 сопрограмма asyncio.to_thread упрощает делегирование файлового ввода-вывода пулу потоков, предоставляемому библиотекой asyncio.
Под капотом цикл событий asyncio обращается к .send, чтобы привести в действие ваши сопрограммы, а ваши сопрограммы с помощью await вызывают другие сопрограммы, в т. ч. библиотечные. await заимствует большую часть реализации у предложения yield from, которое также обращается к .send для управления сопрограммами.
Цепочка await в конце концов достигает низкоуровневого объекта, допускающего ожидание, который возвращает генератор, к которому цикл событий может обращаться в ответ на такие события, как срабатывание таймера или сетевой ввод-вывод. Низкоуровневые объекты, допускающие ожидание, и генераторы в конце таких цепочек await находятся глубоко внутри библиотек, они не являются частью их API и могут быть расширениями, написанными на C.
Для достижения максимальной производительности при работе с asyncio мы должны заменить все функции, осуществляющие ввод-вывод, асинхронными версиями, которые активируются в результате выполнения await или asyncio.create_task, для того чтобы управление возвращалось циклу событий, пока функция ждет завершения ввода-вывода.
У asyncpg есть важное достоинство – он позволяет обойти отсутствие в PostgreSQL поддержки высокой конкурентности (в этой СУБД используется один серверный процесс на каждое подключение), поскольку реализует пул подключений для внутреннего подключения к самой Postgres.
Эдсгер Дейкстра изобрел семафор в начале 1960-х годов. Идея простая, но настолько гибкая, что большинство других объектов синхронизации, например блокировки и барьеры, можно построить на основе семафоров. В стандартной библиотеке Python есть три класса Semaphore: по одному в модулях threading,multiprocessing и asyncio.
В классе asyncio.Semaphore имеется внутренний счетчик, который уменьшается на 1 всякий раз, как выполняется await для метода-сопрограммы .acquire(), и увеличивается на 1 при вызове метода .release(), который не является сопрограммой, потому что никогда не блокирует выполнение. Начальное значение счетчика задается при создании объекта Semaphore:
semaphore = asyncio.Semaphore(concur_req)
Ожидание .acquire() не приводит к задержке, когда счетчик больше 0, но если счетчик равен 0, то .acquire() приостанавливает ожидающую сопрограмму до тех пор, пока какая-нибудь другая сопрограмма не вызовет .release() для того же семафора, увеличив тем самым счетчик. Вместо того чтобы обращаться к этим методам напрямую, безопаснее использовать semaphore как асинхронный контекстный менеджер:
async with semaphore:
image = await get_flag(client, base_url, cc)
Стоит написать первое async def, как в программе неизбежно будут появляться все новые и новые async def, await,
async with и async for. И внезапно использование неасинхронных библиотек становится проблемой.
Атрибуты-данные и методы в Python носят общее название «атрибуты»; метод – это просто вызываемый атрибут. Помимо атрибутов-данных и методов,мы можем создавать еще свойства, позволяющие заменить открытые атрибуты-данные методами-акцессорами (т. е. методами чтения и установки), не изменяя интерфейс класса.
Пользовательский класс, в котором имеется метод getattr, может реализовать вариант динамических атрибутов, который я называю виртуальными атрибутами; они не объявлены в исходном коде класса и отсутствуют в экземпляре dict, но могут быть получены из какого-то другого места или вычислены «на лету», когда программа пытается прочитать несуществующий атрибут, например obj.no_such_attr.
Функция keyword.iskeyword(…) позволяет проверить, является ли строка ключевым словом языка.
#python #codegems
Встроенная функция property часто используется как декоратор, но в действительности она является классом. В Python функции и классы нередко взаимозаменяемы, поскольку являются вызываемыми объектами и не существует оператора new для создания объекта, поэтому вызов конструктора ничем не отличается от вызова фабричной функции. Вот полная сигнатура конструктора класса property: property(fget=None, fset=None, fdel=None, doc=None).
Функция vars не умеет работать с классами, в которых определен атрибут slots и нет атрибута dict (в отличие от функции dir, которая справляется с такими экземплярами).
Без аргумента vars() делает то же самое, что locals(): возвращает словарь, описывающий локальную область видимости.
Метод getattr всегда вызывается после getattribute и только в том случае, когда getattribute возбуждает исключение AttributeError. Чтобы при
получении атрибутов obj не возникало бесконечной рекурсии, в реализации getattribute следует использовать super().getattribute(obj, name).
Встроенный тип type на самом деле является метаклассом – классом по умолчанию для определенных пользователем классов.
В способе обработки атрибутов в Python существует важная асимметрия. При чтении атрибута через экземпляр обычно возвращается атрибут, определенный в этом экземпляре, а если такого атрибута в экземпляре не существует, то атрибут класса. С другой стороны, в случае присваивания атрибуту экземпляра обычно создается атрибут в этом экземпляре, а класс вообще никак не затрагивается. Эта асимметрия распространяется и на дескрипторы, в результате чего образуются две категории дескрипторов, различающиеся наличием или отсутствием метода set. Если set присутствует, то класс является переопределяющим дескриптором, иначе непереопределяющим.
Требование явно объявлять self первым аргументом методов – одно из противоречивых проектных решений в Python.Простота – даже элегантность – реализации достигается за счет пользовательского интерфейса: сигнатура метода – def zfill(self, width) – визуально не соответствует его вызову – label.zfill(8).
Метапрограммирование классов – это искусство создания или настройки классов во время выполнения. Классы в Python – полноправные объекты, поэтому функция может в любой момент создать новый класс, не используя ключевое слово class. Декораторы классов – также функции, которые дополнительно умеют инспектировать и изменять декорированный класс и даже заменять его другим. Наконец, метаклассы – самое продвинутое средство метапрограммирования классов: они позволяют создавать целые категории классов со специальными характеристиками.
Обычно мы воспринимаем type как функцию, которая возвращает класс объекта, потому что именно это делает выражение type(my_object): возвращает my_object.class.
Однако type – это класс, который создает новый класс, если вызывается с тремя аргументами. Рассмотрим следующий простой класс:
С помощью конструктора type мы можем создать MyClass во время выполнения:
Этот вызов type функционально эквивалентен предыдущему предложению
блока class MyClass.
Встроенная функция property часто используется как декоратор, но в действительности она является классом. В Python функции и классы нередко взаимозаменяемы, поскольку являются вызываемыми объектами и не существует оператора new для создания объекта, поэтому вызов конструктора ничем не отличается от вызова фабричной функции. Вот полная сигнатура конструктора класса property: property(fget=None, fset=None, fdel=None, doc=None).
Функция vars не умеет работать с классами, в которых определен атрибут slots и нет атрибута dict (в отличие от функции dir, которая справляется с такими экземплярами).
Без аргумента vars() делает то же самое, что locals(): возвращает словарь, описывающий локальную область видимости.
Метод getattr всегда вызывается после getattribute и только в том случае, когда getattribute возбуждает исключение AttributeError. Чтобы при
получении атрибутов obj не возникало бесконечной рекурсии, в реализации getattribute следует использовать super().getattribute(obj, name).
Встроенный тип type на самом деле является метаклассом – классом по умолчанию для определенных пользователем классов.
В способе обработки атрибутов в Python существует важная асимметрия. При чтении атрибута через экземпляр обычно возвращается атрибут, определенный в этом экземпляре, а если такого атрибута в экземпляре не существует, то атрибут класса. С другой стороны, в случае присваивания атрибуту экземпляра обычно создается атрибут в этом экземпляре, а класс вообще никак не затрагивается. Эта асимметрия распространяется и на дескрипторы, в результате чего образуются две категории дескрипторов, различающиеся наличием или отсутствием метода set. Если set присутствует, то класс является переопределяющим дескриптором, иначе непереопределяющим.
Требование явно объявлять self первым аргументом методов – одно из противоречивых проектных решений в Python.Простота – даже элегантность – реализации достигается за счет пользовательского интерфейса: сигнатура метода – def zfill(self, width) – визуально не соответствует его вызову – label.zfill(8).
Метапрограммирование классов – это искусство создания или настройки классов во время выполнения. Классы в Python – полноправные объекты, поэтому функция может в любой момент создать новый класс, не используя ключевое слово class. Декораторы классов – также функции, которые дополнительно умеют инспектировать и изменять декорированный класс и даже заменять его другим. Наконец, метаклассы – самое продвинутое средство метапрограммирования классов: они позволяют создавать целые категории классов со специальными характеристиками.
Обычно мы воспринимаем type как функцию, которая возвращает класс объекта, потому что именно это делает выражение type(my_object): возвращает my_object.class.
Однако type – это класс, который создает новый класс, если вызывается с тремя аргументами. Рассмотрим следующий простой класс:
class MyClass(MySuperClass, MyMixin):
x = 42
def x2(self):
return self.x * 2
С помощью конструктора type мы можем создать MyClass во время выполнения:
MyClass = type('MyClass',
(MySuperClass, MyMixin),
{'x': 42, 'x2': lambda self: self.x * 2},
)
Этот вызов type функционально эквивалентен предыдущему предложению
блока class MyClass.
#python #codegems
Дескрипторы – это способ повторного использования одной и той же логики доступа в нескольких атрибутах. Например, типы полей в объектно-ориентированных отображениях вроде Django ORM и SQL Alchemy – дескрипторы, управляющие потоком данных от полей в записи базы данных к атрибутам Python-объекта и обратно. Дескриптор – это класс, который реализует динамический протокол, содержащий методы get, set и delete. Класс property реализует весь протокол дескриптора.
Пример использования дескриптора:
Глядя на пример, можно подумать, что кода слишком много для управления всего-то парой атрибутов, но важно понимать, что логика дескриптора теперь вынесена в отдельную кодовую единицу: класс Quantity. Обычно мы не определяем дескриптор в том же модуле, в каком он используется, а заводим отдельный служебный модуль, предназначенный для использования во всем приложении, а то и во многих приложениях, если разрабатывается библиотека или фреймфорк.
Воображаемый магазин натуральных пищевых продуктов столкнулся с неожиданной проблемой: каким-то образом была создана строка заказа с пустым описанием, и теперь заказ невозможно выполнить. Чтобы предотвратить такие инциденты в будущем, мы создадим новый дескриптор, NonBlank. Проектируя NonBlank, мы обнаруживаем, что он очень похож на дескриптор Quantity, а отличается только логика проверки. Это наводит на мысль о рефакторинге и заведении двух базовых классов: завести абстрактный класс Validated, переопределяющий метод set, вызывая метод validate, который должен быть реализован в подклассах. Затем мы переписываем Quantity и реализуем NonBlank, наследуя классу Validated, так что остается лишь написать методы validate. Соотношение между классами Validated, Quantity и NonBlank – пример паттерна проектирования Шаблонный метод, который в классической книге «Паттерны проектирования» описывается следующим образом: Шаблонный метод определяет алгоритм в терминах абстрактных операций, которые переопределяются в подклассах для обеспечения конкретного поведения.
Дескрипторы – это способ повторного использования одной и той же логики доступа в нескольких атрибутах. Например, типы полей в объектно-ориентированных отображениях вроде Django ORM и SQL Alchemy – дескрипторы, управляющие потоком данных от полей в записи базы данных к атрибутам Python-объекта и обратно. Дескриптор – это класс, который реализует динамический протокол, содержащий методы get, set и delete. Класс property реализует весь протокол дескриптора.
Пример использования дескриптора:
class Quantity:
def __set_name__(self, owner, name):
self.storage_name = name
def __set__(self, instance, value):
if value > 0:
instance.__dict__[self.storage_name] = value
else:
msg = f'{self.storage_name} must be > 0'
raise ValueError(msg)
# __get__ не нужен
class LineItem:
weight = Quantity()
price = Quantity()
def __init__(self, description, weight, price):
self.description = description
self.weight = weight
self.price = price
def subtotal(self):
return self.weight * self.price
Глядя на пример, можно подумать, что кода слишком много для управления всего-то парой атрибутов, но важно понимать, что логика дескриптора теперь вынесена в отдельную кодовую единицу: класс Quantity. Обычно мы не определяем дескриптор в том же модуле, в каком он используется, а заводим отдельный служебный модуль, предназначенный для использования во всем приложении, а то и во многих приложениях, если разрабатывается библиотека или фреймфорк.
Воображаемый магазин натуральных пищевых продуктов столкнулся с неожиданной проблемой: каким-то образом была создана строка заказа с пустым описанием, и теперь заказ невозможно выполнить. Чтобы предотвратить такие инциденты в будущем, мы создадим новый дескриптор, NonBlank. Проектируя NonBlank, мы обнаруживаем, что он очень похож на дескриптор Quantity, а отличается только логика проверки. Это наводит на мысль о рефакторинге и заведении двух базовых классов: завести абстрактный класс Validated, переопределяющий метод set, вызывая метод validate, который должен быть реализован в подклассах. Затем мы переписываем Quantity и реализуем NonBlank, наследуя классу Validated, так что остается лишь написать методы validate. Соотношение между классами Validated, Quantity и NonBlank – пример паттерна проектирования Шаблонный метод, который в классической книге «Паттерны проектирования» описывается следующим образом: Шаблонный метод определяет алгоритм в терминах абстрактных операций, которые переопределяются в подклассах для обеспечения конкретного поведения.
import abc
class Validated(abc.ABC):
def __set_name__(self, owner, name):
self.storage_name = name
def __set__(self, instance, value):
value = self.validate(self.storage_name, value)
instance.__dict__[self.storage_name] = value
@abc.abstractmethod
def validate(self, name, value):
"""вернуть проверенное значение или возбудить ValueError"""
class Quantity(Validated):
"""число, большее нуля"""
def validate(self, name, value):
if value <= 0:
raise ValueError(f'{name} must be > 0')
return value
class NonBlank(Validated):
"""строка, содержащая хотя бы один символ, отличный от пробела"""
def validate(self, name, value):
value = value.strip()
if not value:
raise ValueError(f'{name} cannot be blank')
return value
import model_v5 as model
class LineItem:
description = model.NonBlank()
weight = model.Quantity()
price = model.Quantity()
def __init__(self, description, weight, price):
self.description = description
self.weight = weight
self.price = price
def subtotal(self):
return self.weight * self.price
#python #books
Ссылки на посты по книжке "Л. Рамальо. Python – к вершинам мастерства: Лаконичное и эффективное программирование" (в оригинале - Fluent Python, 2nd Edition). Содержат материал, который показался мне интересным и вошёл в категорию #codegems.
Затрагиваются механизмы сопоставления (match), классы данных и их аналоги, аннотирование типами, инструменты itertools, работа с классами/ООП, генераторы, контекстные менеджеры, асинхронка, дескрипторы классов.
Пробегитесь по темам, если есть незнакомые слова, возможно, есть смысл перечитать актуальную доку Питон )
1. [], {} и ()/match/ChainMap/MappingProxyType
2. class init/dict/json
3. unicode: NFC/NDF, strxfrm/NamedTuple/dataclass
4. more dataclass/typehints
5. weakrefs/functional programming/more typehints
6. Any/|/TypeVar/TypeAlias/typing.Protocol
7. positional-only/closures/singledispath/decorator via class
8. getattr/reduce via initializer/zip,zip_longest/principle of failing fast
9. goose typing/vurtual subclass/Hashable/ABC/Decimal
10. UserDict, UserList, UserString/MRO/mixin/get_annotations
11. (sub)generator/coprogram/type: ignore/with/@contextmanager
12. else in for,while,try/scientific sins/GIL/getswitchinterval/asyncio
13. asyncio.to_thread/asyncpg/asyncio.Semaphore/async with/keyword.iskeyword
14. property/vars/metaprogramming
15. class descriptors
Если решите читать книгу - ТОЛЬКО в оригинале, русский перевод плох.
Ссылки на посты по книжке "Л. Рамальо. Python – к вершинам мастерства: Лаконичное и эффективное программирование" (в оригинале - Fluent Python, 2nd Edition). Содержат материал, который показался мне интересным и вошёл в категорию #codegems.
Затрагиваются механизмы сопоставления (match), классы данных и их аналоги, аннотирование типами, инструменты itertools, работа с классами/ООП, генераторы, контекстные менеджеры, асинхронка, дескрипторы классов.
Пробегитесь по темам, если есть незнакомые слова, возможно, есть смысл перечитать актуальную доку Питон )
1. [], {} и ()/match/ChainMap/MappingProxyType
2. class init/dict/json
3. unicode: NFC/NDF, strxfrm/NamedTuple/dataclass
4. more dataclass/typehints
5. weakrefs/functional programming/more typehints
6. Any/|/TypeVar/TypeAlias/typing.Protocol
7. positional-only/closures/singledispath/decorator via class
8. getattr/reduce via initializer/zip,zip_longest/principle of failing fast
9. goose typing/vurtual subclass/Hashable/ABC/Decimal
10. UserDict, UserList, UserString/MRO/mixin/get_annotations
11. (sub)generator/coprogram/type: ignore/with/@contextmanager
12. else in for,while,try/scientific sins/GIL/getswitchinterval/asyncio
13. asyncio.to_thread/asyncpg/asyncio.Semaphore/async with/keyword.iskeyword
14. property/vars/metaprogramming
15. class descriptors
Если решите читать книгу - ТОЛЬКО в оригинале, русский перевод плох.
Telegram
Aspiring Data Science
#python #codegems
По умолчанию любой экземпляр пользовательского класса считается истинным, но положение меняется, если реализован хотя бы один из методов bool или len. Функция bool(x), по существу, вызывает x.bool() и использует полученный результат. Если…
По умолчанию любой экземпляр пользовательского класса считается истинным, но положение меняется, если реализован хотя бы один из методов bool или len. Функция bool(x), по существу, вызывает x.bool() и использует полученный результат. Если…
#python #pyccolo
Хакинг и сабклассинг питона. Для меня это уж слишком, но вдруг кому ТАКОЙ уровень гибкости нужен.
https://www.youtube.com/watch?v=8UesBrSt7wY
Хакинг и сабклассинг питона. Для меня это уж слишком, но вдруг кому ТАКОЙ уровень гибкости нужен.
https://www.youtube.com/watch?v=8UesBrSt7wY
YouTube
Stephen Macke - Python as a Hackable Language for Interactive Data Science | PyData Global 2023
www.pydata.org
Did you know that the core Python syntax and semantics can be tailored for interactive computing use cases? It turns out that more is possible than what you would expect! For example, at the most basic level, Jupyter supports basic syntax…
Did you know that the core Python syntax and semantics can be tailored for interactive computing use cases? It turns out that more is possible than what you would expect! For example, at the most basic level, Jupyter supports basic syntax…
#python #codegems #chainmap
https://towardsdev.com/what-99-of-python-developers-dont-know-about-chainmap-and-why-it-s-a-game-changer-d9e749f965df
https://towardsdev.com/what-99-of-python-developers-dont-know-about-chainmap-and-why-it-s-a-game-changer-d9e749f965df
Medium
What 99% of Python Developers Don’t Know About ChainMap (And Why It’s a Game-Changer
“Knowledge is power, but knowledge without implementation is useless.” — Charles F. Kettering
#python #optuna #nogil
Что интересно, в Оптуне потестили питон 3.13 без GIL-а, получили по сути ухудшение скорости.
https://medium.com/optuna/overview-of-python-free-threading-v3-13t-support-in-optuna-ad9ab62a11ba
Что интересно, в Оптуне потестили питон 3.13 без GIL-а, получили по сути ухудшение скорости.
https://medium.com/optuna/overview-of-python-free-threading-v3-13t-support-in-optuna-ad9ab62a11ba
Medium
Overview of Python Free Threading (v3.13t) Support in Optuna
In Python 3.13, experimental support for free threading has been introduced, as proposed in PEP 703. Until now, the Python interpreter…
#python #functools
https://blog.stackademic.com/pythons-functools-library-the-hidden-gem-for-advanced-programming-23760d8e3de5
https://blog.stackademic.com/pythons-functools-library-the-hidden-gem-for-advanced-programming-23760d8e3de5
Medium
Python’s functools Library: The Hidden Gem for Advanced Programming
When was the last time you used Python’s functools module? If your answer is "never" or "rarely," you’re not alone. Often overshadowed by…
#python #speed
Хорошее перечисление основных подходов к оптимизации питоновского кода.
https://medium.com/@yashwanthnandam/think-python-is-slow-try-these-hacks-for-3x-faster-scripts-today-fbe258ec93bd
Хорошее перечисление основных подходов к оптимизации питоновского кода.
https://medium.com/@yashwanthnandam/think-python-is-slow-try-these-hacks-for-3x-faster-scripts-today-fbe258ec93bd
Medium
Think Python Is Slow? Try These Hacks for 3x Faster Scripts Today
Why investing time in optimization pays off big
#python #codestyle #codegems
Есть о чём задуматься, типа конструкций
https://levelup.gitconnected.com/12-production-grade-python-code-styles-ive-picked-up-from-work-ad32d8ae630d
Есть о чём задуматься, типа конструкций
for elem in mylist or []:
https://levelup.gitconnected.com/12-production-grade-python-code-styles-ive-picked-up-from-work-ad32d8ae630d
Medium
12 Production-Grade Python Code Styles I’ve Picked Up From Work
Read Free…
#python #typing
Про Final не знал. Self, TypeAlias, Literal заслуживают внимания.
На самом деле всё ещё сложнее с TypeVar.
https://medium.com/techtofreedom/8-levels-of-using-type-hints-in-python-a6717e28f8fd
Про Final не знал. Self, TypeAlias, Literal заслуживают внимания.
На самом деле всё ещё сложнее с TypeVar.
https://medium.com/techtofreedom/8-levels-of-using-type-hints-in-python-a6717e28f8fd
Medium
8 Levels of Using Type Hints in Python
To make your programs more readable and easier to debug
#python #security #pypi
"Проблема возникла из-за удаления зависимости msgspec-python313-pre из репозитория PyPI (Python Package Index), который содержит тысячи сторонних модулей для Python. Злоумышленники добавили в репозиторий вредоносный пакет с тем же именем, который даёт им возможность удалённого выполнения произвольного кода на уязвимых системах, что может привести к компрометации данных, краже информации и полному контролю над заражённым ПК."
https://3dnews.ru/1119504/millioni-kompyuterov-okazalis-pod-ugrozoy-vzloma-izza-kriticheskoy-uyazvimosti-svyazannoy-s-python
"Проблема возникла из-за удаления зависимости msgspec-python313-pre из репозитория PyPI (Python Package Index), который содержит тысячи сторонних модулей для Python. Злоумышленники добавили в репозиторий вредоносный пакет с тем же именем, который даёт им возможность удалённого выполнения произвольного кода на уязвимых системах, что может привести к компрометации данных, краже информации и полному контролю над заражённым ПК."
https://3dnews.ru/1119504/millioni-kompyuterov-okazalis-pod-ugrozoy-vzloma-izza-kriticheskoy-uyazvimosti-svyazannoy-s-python
3DNews - Daily Digital Digest
Миллионы компьютеров оказались под угрозой взлома из-за критической уязвимости, связанной с Python
В популярном пакете объектно-ориентированного языка программирования Python — python-json-logger — обнаружена критическая уязвимость, которой присвоен код CVE-2025-27607.