Telegram Group Search
Некоторым генераторам нужно возвращать все элементы другого генератора:


>>> def enclose(gen, before='{', after='}'):
... yield before
... for x in gen:
... yield x
... yield after
...
>>> list(enclose(range(5)))
['{', 0, 1, 2, 3, 4, '}']


Однако предпочтительнее использовать yield from:


>>> def enclose(gen, before='{', after='}'):
... yield before
... yield from gen
... yield after


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

👉@BookPython
Самые интересные фичи Python 3.12, которые уже можно тестить и встраивать в проекты


1️⃣ Улучшенный match-case

Теперь можно использовать «захват» значений прямо в паттернах:


def http_status(code):
match code:
case 200 | 201 | 202 as ok:
return f"Success: {ok}"
case 400 as bad | 404 as bad:
return f"Client error: {bad}"
case _:
return "Other"


Большая гибкость и меньше «шаблонных» переменных!



2️⃣ Новый оператор f”{…=}" для отладки

Позволяет вывести и имя, и значение переменной в одной строке:


user = "Alice"
age = 29
print(f"{user=}, {age=}")
# Выведет: user='Alice', age=29


Больше никаких лишних print("user", user)!



3️⃣ Оптимизация работы с памятью и скорость

Команда CPython продолжает ускорение интерпретатора:

* Выделение объектов стало быстрее
* Сборщик мусора реже «паузит» приложение

Это особенно заметно в тяжёлых сервисах и бэкендах.



4️⃣ Новые API для типов

Добавили typing.Self и более гибкие Generic-типизации:


from typing import Self

class Builder:
def set_name(self, name: str) -> Self:
self.name = name
return self

b = Builder().set_name("Demo")


Удобнее писать цепочки вызовов без «# type: ignore»!



💡 Что попробовать прямо сейчас?

1. Установить Python 3.12 pre-release:


pyenv install 3.12.0b4

2. Переписать пару функций с match-case.
3. Пощупать f"{var=}" в дебаге.

👉@BookPython
Python позволяет работать с путями файловой системы через модуль os.path. Модуль содержит множество функций, которые обрабатывают строки как пути и выполняют полезные операции, такие как объединение путей и прочее:


>>> import os.path
>>> os.path.join('/usr', 'local')
'/usr/local'
>>> os.path.dirname('/var/log')
'/var'


Однако, начиная с Python 3.4, доступен новый модуль pathlib, предлагающий объектно-ориентированный подход:


>>> from pathlib import Path
>>> Path('/usr') / Path('local')
PosixPath('/usr/local')
>>> Path('/usr') / 'local'
PosixPath('/usr/local')
>>> Path('/var/log').parent
PosixPath('/var')
>>> Path('/var/log').parent.name
'var'


👉@BookPython
В Python объекты хранят свои атрибуты в словарях, доступ к которым можно получить через магический атрибут dict:


class A: pass
a = A()
a.x = 1
a.__dict__
# {'x': 1}


При прямом доступе к этому словарю можно даже создать атрибуты, которые не являются допустимыми идентификаторами Python (то есть получить их через стандартный синтаксис obj.attr не получится):


a.__dict__[' '] = ' '
getattr(a, ' ')
# ' '


Можно также попросить Python хранить атрибуты непосредственно в памяти (как у простых структур C) с помощью slots. Это экономит память и немного ускоряет доступ к атрибутам, так как не происходит поиска в словаре.


class Point:
__slots__ = ['x', 'y']


Есть несколько моментов, которые нужно помнить при использовании slots. Во-первых, нельзя задавать атрибуты, не указанные в slots. Во-вторых, если класс наследуется от класса с slots, его slots не перекрывают родительские, а добавляются к ним:


class Parent: __slots__ = ['x']
class Child(Parent): __slots__ = ['y']
c = Child()
c.x = 1
c.y = 2


В-третьих, нельзя наследоваться сразу от двух разных классов с непустыми slots, даже если они совпадают.

Помни, что slots предназначены для оптимизации, а не для ограничения набора атрибутов.

👉@BookPython
В Python можно создавать вызываемые объекты не только с помощью функций (def или lambda). Объект также считается вызываемым, если у него реализован магический метод call:


class truncater:
def __init__(self, length):
self._length = length

def __call__(self, s):
return s[0:self._length]


print(truncater(4)('abcdabcd')) # abcd


Поскольку декоратор по сути является функцией высшего порядка, его также можно реализовать в виде вызываемого объекта вместо функции:


class cached:
def __init__(self, func):
self._func = func
self._cache = {}

def __call__(self, arg):
if arg not in self._cache:
self._cache[arg] = self._func(arg)

return self._cache[arg]


@cached
def sqr(x):
return x * x


👉@BookPython
Проблема с вызовом repr других объектов в своём собственном методе repr заключается в том, что нельзя гарантировать, что ни один из других объектов не равен self, и вызов не окажется рекурсивным:


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**
return f'{class_name}({self.left!r}, {self.right!r})'


Теперь всё работает:


In : p = Pair(1, 2)
In : p.right = p
In : p
Out: Pair(1, ...)


👉@BookPython
🚀 Подборка Telegram каналов для программистов

Системное администрирование, DevOps 📌

https://www.tg-me.com/bash_srv Bash Советы
https://www.tg-me.com/win_sysadmin Системный Администратор Windows
https://www.tg-me.com/sysadmin_girl Девочка Сисадмин
https://www.tg-me.com/srv_admin_linux Админские угодья
https://www.tg-me.com/linux_srv Типичный Сисадмин
https://www.tg-me.com/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://www.tg-me.com/linux_odmin Linux: Системный администратор
https://www.tg-me.com/devops_star DevOps Star (Звезда Девопса)
https://www.tg-me.com/i_linux Системный администратор
https://www.tg-me.com/linuxchmod Linux
https://www.tg-me.com/sys_adminos Системный Администратор
https://www.tg-me.com/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://www.tg-me.com/sysadminof Книги для админов, полезные материалы
https://www.tg-me.com/i_odmin Все для системного администратора
https://www.tg-me.com/i_odmin_book Библиотека Системного Администратора
https://www.tg-me.com/i_odmin_chat Чат системных администраторов
https://www.tg-me.com/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://www.tg-me.com/sysadminoff Новости Линукс Linux

1C разработка 📌
https://www.tg-me.com/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://www.tg-me.com/DevLab1C 1С:Предприятие 8
https://www.tg-me.com/razrab_1C 1C Разработчик
https://www.tg-me.com/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://www.tg-me.com/rabota1C_rus Вакансии для программистов 1С

Программирование C++📌
https://www.tg-me.com/cpp_lib Библиотека C/C++ разработчика
https://www.tg-me.com/cpp_knigi Книги для программистов C/C++
https://www.tg-me.com/cpp_geek Учим C/C++ на примерах

Программирование Python 📌
https://www.tg-me.com/pythonofff Python академия.
https://www.tg-me.com/Библиотека Python разработчика/com.BookPython Библиотека Python разработчика
https://www.tg-me.com/python_real Python подборки на русском и английском
https://www.tg-me.com/python_360 Книги по Python

Java разработка 📌
https://www.tg-me.com/BookJava Библиотека Java разработчика
https://www.tg-me.com/java_360 Книги по Java Rus
https://www.tg-me.com/java_geek Учим Java на примерах

GitHub Сообщество 📌
https://www.tg-me.com/Githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://www.tg-me.com/database_info Все про базы данных

Мобильная разработка: iOS, Android 📌
https://www.tg-me.com/developer_mobila Мобильная разработка
https://www.tg-me.com/kotlin_lib Подборки полезного материала по Kotlin

Фронтенд разработка 📌
https://www.tg-me.com/frontend_1 Подборки для frontend разработчиков
https://www.tg-me.com/frontend_sovet Frontend советы, примеры и практика!
https://www.tg-me.com/React_lib Подборки по React js и все что с ним связано

Разработка игр 📌
https://www.tg-me.com/game_devv Все о разработке игр

Библиотеки 📌
https://www.tg-me.com/book_for_dev Книги для программистов Rus
https://www.tg-me.com/programmist_of Книги по программированию
https://www.tg-me.com/proglb Библиотека программиста
https://www.tg-me.com/bfbook Книги для программистов

БигДата, машинное обучение 📌
https://www.tg-me.com/bigdata_1 Big Data, Machine Learning

Программирование 📌
https://www.tg-me.com/bookflow Лекции, видеоуроки, доклады с IT конференций
https://www.tg-me.com/rust_lib Полезный контент по программированию на Rust
https://www.tg-me.com/golang_lib Библиотека Go (Golang) разработчика
https://www.tg-me.com/itmozg Программисты, дизайнеры, новости из мира IT
https://www.tg-me.com/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻
https://www.tg-me.com/nodejs_lib Подборки по Node js и все что с ним связано
https://www.tg-me.com/ruby_lib Библиотека Ruby программиста
https://www.tg-me.com/lifeproger Жизнь программиста. Авторский канал.

QA, тестирование 📌
https://www.tg-me.com/testlab_qa Библиотека тестировщика

Шутки программистов 📌
https://www.tg-me.com/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://www.tg-me.com/thehaking Канал о кибербезопасности
https://www.tg-me.com/xakep_2 Хакер Free

Книги, статьи для дизайнеров 📌
https://www.tg-me.com/ux_web Статьи, книги для дизайнеров

Математика 📌
https://www.tg-me.com/Pomatematike Канал по математике
https://www.tg-me.com/phis_mat Обучающие видео, книги по Физике и Математике
https://www.tg-me.com/matgeoru Математика | Геометрия | Логика

Excel лайфхак📌
https://www.tg-me.com/Excel_lifehack

https://www.tg-me.com/mir_teh Мир технологий (Technology World)

Вакансии 📌
https://www.tg-me.com/sysadmin_rabota Системный Администратор
https://www.tg-me.com/progjob Вакансии в IT
Если вы хотите перехватить и IndexError, и KeyError, вы можете и должны использовать LookupError — их общего предка. Это оказывается полезным при работе со сложными вложенными данными:


try:
db_host = config['databases'][0]['hosts'][0]
except LookupError:
db_host = 'localhost'


👉@BookPython
Если во время итерации нужно получить доступ к соседним элементам, можно создать итератор, который сделает это автоматически.


from itertools import tee

def neighbours(iterable, n):
neighbours = tee(iterable, n)
for i, neighbour in enumerate(neighbours):
for _ in range(i):
next(neighbour)

return zip(*neighbours)

fibb = [1, 1, 2, 3, 5, 8, 13, 21]

for a, b, c in neighbours(fibb, 3):
assert c == a + b


В этом примере мы разветвляем исходный итерируемый объект с помощью tee, затем сдвигаем полученные итераторы с помощью next, чтобы второй начинался со второго элемента исходного итерируемого объекта, а третий — с третьего, и затем объединяем их обратно с помощью zip.

👉@BookPython
PEP 424 позволяет генераторам и другим итерируемым объектам, у которых нет заранее определённого точного размера, предоставлять «подсказку» о длине. Например, следующий генератор, скорее всего, вернёт примерно 50 элементов:


(x for x in range(100) if random() > 0.5)


Если вы пишете свой итерируемый объект и хотите добавить такую подсказку, определите метод __length_hint__. Если же длина известна точно, лучше использовать len.

Если вы используете итерируемый объект и хотите узнать его ожидаемую длину, применяйте функцию operator.length_hint.

👉@BookPython
Каждый класс Python имеет два «магических» атрибута, которые можно использовать для получения информации о его базовых классах.

Первый — __bases__; он возвращает непосредственных родителей класса:


class A:
pass

class B(A):
pass

class C(A):
pass

class D(B, C):
pass


print(D.__bases__)
# (<class '__main__.B'>, <class '__main__.C'>)


Второй —


class B
он возвращает кортеж со всеми классами, которые задействованы при разрешении методов (отсюда и название), то есть родителей, их родителей и так далее:


print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)


👉@BookPython
Класс объекта доступен через атрибут __class__:


>>> [1, 2].__class__
<class 'list'>


Однако более привычный способ получить класс — использовать функцию type. Это также единственный способ, который работает для классов старого стиля.


>>> type([1, 2])
<class 'list'>


Кроме того, если вы хотите проверить, является ли некоторый объект экземпляром данного класса, следует использовать isinstance вместо прямого сравнения:


>>> class A:
... pass
...
>>> class B(A):
... pass
...
>>> type(B())
<class '__main__.B'>
>>> isinstance(B(), A)
True


👉@BookPython
Оператор in можно использовать с генераторами: x in g. Python будет итерировать g, пока x не найдётся или генератор не исчерпается.


>>> def g():
... print(1)
... yield 1
... print(2)
... yield 2
... print(3)
... yield 3
...
>>> 2 in g()
1
2
True


Однако range() делает для вас больше. В нём переопределён магический метод __contains__, который позволяет оператору in работать с сложностью O(1):


In [1]: %timeit 10**20 in range(10**30)
375 ns ± 10.7 ns per loop


Учтите, что это не работает для функции xrange() в Python 2.

👉@BookPython
В Python операторы += и + являются разными. За их поведение отвечают методы __iadd__ и __add__ соответственно.


class A:
def __init__(self, x):
self.x = x

def __iadd__(self, another):
self.x += another.x
return self

def __add__(self, another):
return type(self)(self.x + another.x)


Если __iadd__ не определён, выражение a += b сводится к простому a = a + b.

Обычно разница между += и + в том, что первый изменяет объект, а второй создаёт новый:


>>> a = [1, 2, 3]
>>> b = a
>>> a += [4]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a = a + [5]
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]


👉@BookPython
В Python блок else может располагаться не только после if, но и после for и while. Код внутри else выполняется, если цикл не был прерван оператором break.

Обычный способ использования этого — найти что-то в цикле и выйти из него через break, когда нужный элемент найден:


>>> first_odd = None
>>> for x in [2, 3, 4, 5]:
... if x % 2 == 1:
... first_odd = x
... break
... else:
... raise ValueError('В списке нет нечетных элементов')
...
>>> first_odd
3



>>> for x in [2, 4, 6]:
... if x % 2 == 1:
... first_odd = x
... break
... else:
... raise ValueError('В списке нет нечетных элементов')
...
...
ValueError: В списке нет нечетных элементов


👉@BookPython
Иногда нужно выполнить блок кода с несколькими менеджерами контекста:


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


Если же число менеджеров контекста заранее неизвестно, лучше подойдёт более продвинутый инструмент. contextlib.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
]


👉@BookPython
Все объекты, которые в настоящий момент существуют в памяти интерпретатора, можно получить с помощью gc.get_objects():


In [1]: class A:
...: def __init__(self, x):
...: self._x = x
...:
...: def __repr__(self):
...: class_name = type(self).__name__
...: x = self._x
...: return f'{class_name}({x!r})'
...:

In [2]: A(1)
Out[2]: A(1)

In [3]: A(2)
Out[3]: A(2)

In [4]: A(3)
Out[4]: A(3)

In [5]: [x for x in gc.get_objects() if isinstance(x, A)]
Out[5]: [A(1), A(2), A(3)]


👉@BookPython
Начиная с Python 3.0, при возникновении нового исключения внутри блока except перехваченное исключение автоматически сохраняется в атрибуте __context__ создаваемого исключения. В результате при выводе будут показаны оба исключения:


try:
1 / 0
except ZeroDivisionError:
raise ValueError('Zero!')



(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!


Кроме того, вы можете явно указать причинное исключение, использовав конструкцию raise … from. Тогда в атрибут __cause__ нового исключения будет помещено исходное:


division_error = None

try:
1 / 0
except ZeroDivisionError as e:
division_error = e

raise ValueError('Zero!') from division_error



(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!


👉@BookPython
In:


int('୧৬𝟙༣')


Out:


1613


Цифры 0 1 2 3 4 5 6 7 8 9 — это не единственные символы, которые считаются цифрами. Python следует правилам Unicode и считает «цифрами» сотни различных символов. Вот полный список таких символов.

Это влияет на такие функции, как int, unicode.isdecimal и даже re.match:


# Пример 1
int('෯')
# Вывод:
9

# Пример 2
'٢'.isdecimal()
# Вывод:
True

# Пример 3
import re
bool(re.match(r'\d', '౫'))
# Вывод:
True


👉@BookPython
2025/06/13 12:46:51
Back to Top
HTML Embed Code: