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

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

رفتن به کانال در Telegram

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

نمایش بیشتر

📈 تحلیل کانال تلگرام Библиотека Python разработчика | Книги по питону

کانال Библиотека Python разработчика | Книги по питону (@bookpython) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 18 270 مشترک است و جایگاه 7 296 را در دسته فناوری و برنامه‌ها و رتبه 36 842 را در منطقه روسيا دارد.

📊 شاخص‌های مخاطب و پویایی

از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 18 270 مشترک جذب کرده است.

بر اساس آخرین داده‌ها در تاریخ 23 ژوئن, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -99 و در ۲۴ ساعت گذشته برابر -5 بوده و همچنان دسترسی گسترده‌ای حفظ شده است.

  • وضعیت تأیید: تأیید نشده
  • نرخ تعامل (ER): میانگین تعامل مخاطب 5.72% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 2.88% واکنش نسبت به کل مشترکان کسب می‌کند.
  • دسترسی پست‌ها: هر پست به طور میانگین 1 045 بازدید دریافت می‌کند. در اولین روز معمولاً 527 بازدید جمع‌آوری می‌شود.
  • واکنش‌ها و تعامل: مخاطبان به‌طور فعال حمایت می‌کنند؛ میانگین واکنش به هر پست 4 است.
  • علایق موضوعی: محتوا بر موضوعات کلیدی مانند numbers, yield, модуль, none, декоратор تمرکز دارد.

📝 توضیح و سیاست محتوایی

نویسنده این فضا را محل بیان دیدگاه‌های شخصی توصیف می‌کند:
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq

به لطف به‌روزرسانی‌های پرتکرار (آخرین داده در تاریخ 24 ژوئن, 2026)، کانال همواره به‌روز و دارای دسترسی بالاست. تحلیل‌ها نشان می‌دهد مخاطبان به‌طور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامه‌ها تبدیل کرده‌اند.

18 270
مشترکین
-524 ساعت
-247 روز
-9930 روز
جذب مشترکین
ژوئن '26
ژوئن '26
+18
در 0 کانال‌ها
مه '26
+40
در 0 کانال‌ها
Get PRO
آوریل '26
+26
در 0 کانال‌ها
Get PRO
مارس '26
+31
در 0 کانال‌ها
Get PRO
فوریه '26
+62
در 0 کانال‌ها
Get PRO
ژانویه '26
+69
در 0 کانال‌ها
Get PRO
دسامبر '25
+67
در 0 کانال‌ها
Get PRO
نوامبر '25
+97
در 31 کانال‌ها
Get PRO
اکتبر '25
+64
در 1 کانال‌ها
Get PRO
سپتامبر '25
+90
در 36 کانال‌ها
Get PRO
اوت '25
+60
در 0 کانال‌ها
Get PRO
ژوئیه '25
+89
در 27 کانال‌ها
Get PRO
ژوئن '25
+116
در 19 کانال‌ها
Get PRO
مه '25
+119
در 44 کانال‌ها
Get PRO
آوریل '25
+164
در 37 کانال‌ها
Get PRO
مارس '25
+147
در 38 کانال‌ها
Get PRO
فوریه '25
+178
در 31 کانال‌ها
Get PRO
ژانویه '25
+176
در 33 کانال‌ها
Get PRO
دسامبر '24
+158
در 34 کانال‌ها
Get PRO
نوامبر '24
+112
در 33 کانال‌ها
Get PRO
اکتبر '24
+139
در 29 کانال‌ها
Get PRO
سپتامبر '24
+190
در 29 کانال‌ها
Get PRO
اوت '24
+68
در 17 کانال‌ها
Get PRO
ژوئیه '24
+56
در 0 کانال‌ها
Get PRO
ژوئن '24
+95
در 23 کانال‌ها
Get PRO
مه '24
+223
در 18 کانال‌ها
Get PRO
آوریل '24
+174
در 0 کانال‌ها
Get PRO
مارس '24
+240
در 20 کانال‌ها
Get PRO
فوریه '24
+224
در 18 کانال‌ها
Get PRO
ژانویه '24
+287
در 23 کانال‌ها
Get PRO
دسامبر '23
+253
در 24 کانال‌ها
Get PRO
نوامبر '23
+282
در 16 کانال‌ها
Get PRO
اکتبر '23
+319
در 18 کانال‌ها
Get PRO
سپتامبر '23
+342
در 0 کانال‌ها
Get PRO
اوت '23
+264
در 0 کانال‌ها
Get PRO
ژوئیه '23
+292
در 0 کانال‌ها
Get PRO
ژوئن '23
+211
در 0 کانال‌ها
Get PRO
مه '23
+284
در 0 کانال‌ها
Get PRO
آوریل '23
+240
در 0 کانال‌ها
Get PRO
مارس '23
+419
در 0 کانال‌ها
Get PRO
فوریه '23
+147
در 0 کانال‌ها
Get PRO
ژانویه '23
+247
در 0 کانال‌ها
Get PRO
دسامبر '22
+191
در 0 کانال‌ها
Get PRO
نوامبر '22
+174
در 0 کانال‌ها
Get PRO
اکتبر '22
+283
در 0 کانال‌ها
Get PRO
سپتامبر '22
+268
در 0 کانال‌ها
Get PRO
اوت '22
+287
در 0 کانال‌ها
Get PRO
ژوئیه '22
+322
در 0 کانال‌ها
Get PRO
ژوئن '22
+233
در 0 کانال‌ها
Get PRO
مه '22
+258
در 0 کانال‌ها
Get PRO
آوریل '22
+252
در 0 کانال‌ها
Get PRO
مارس '22
+380
در 0 کانال‌ها
Get PRO
فوریه '22
+207
در 0 کانال‌ها
Get PRO
ژانویه '22
+315
در 0 کانال‌ها
Get PRO
دسامبر '21
+211
در 0 کانال‌ها
Get PRO
نوامبر '21
+269
در 0 کانال‌ها
Get PRO
اکتبر '21
+326
در 0 کانال‌ها
Get PRO
سپتامبر '21
+286
در 0 کانال‌ها
Get PRO
اوت '21
+486
در 0 کانال‌ها
Get PRO
ژوئیه '21
+420
در 0 کانال‌ها
Get PRO
ژوئن '21
+368
در 0 کانال‌ها
Get PRO
مه '21
+350
در 0 کانال‌ها
Get PRO
آوریل '21
+387
در 0 کانال‌ها
Get PRO
مارس '21
+568
در 0 کانال‌ها
Get PRO
فوریه '21
+572
در 0 کانال‌ها
Get PRO
ژانویه '21
+777
در 0 کانال‌ها
Get PRO
دسامبر '20
+18 545
در 0 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
24 ژوئن0
23 ژوئن+1
22 ژوئن+1
21 ژوئن0
20 ژوئن+1
19 ژوئن0
18 ژوئن+1
17 ژوئن0
16 ژوئن+2
15 ژوئن0
14 ژوئن+1
13 ژوئن0
12 ژوئن+1
11 ژوئن+1
10 ژوئن0
09 ژوئن+1
08 ژوئن+1
07 ژوئن+3
06 ژوئن+1
05 ژوئن+2
04 ژوئن+1
03 ژوئن0
02 ژوئن0
01 ژوئن0
پست‌های کانال
Генератор можно остановить. Ты можешь явно вызвать g.close(), но обычно это делает сборщик мусора. Когда вызывается close, в точке, где выполнение генератора было приостановлено, выбрасывается исключение GeneratorExit:

def gen():
    try:
        yield 1
        yield 2
    finally:
        print('END')


g = gen()
print(next(g))  # выведет '1'
g.close()       # выведет 'END'
Обрати внимание на три момента: 1. Нельзя использовать yield при обработке GeneratorExit Если в блоке finally попытаться сделать yield, возникнет ошибка RuntimeError:

def gen():
    try:
        yield 1
    finally:
        yield 3  # ошибка!


g = gen()
next(g)
g.close()  # RuntimeError
2. Исключение не выбрасывается, если генератор ещё не запускался В этом случае генератор просто переходит в состояние остановлен, но finally не выполняется:

def gen():
    try:
        yield 1
    finally:
        print('END')


g = gen()
g.close()         # ничего не выводит
print(list(g))    # выведет '[]'
3. close() ничего не делает, если генератор уже завершён Если генератор полностью отработал, close() не вызывает finally повторно и просто игнорируется:

def gen():
    try:
        yield 1
        yield 2
    finally:
        print('END')


g = gen()
print(list(g))     # ['1', '2']
print('Closing now')
g.close()

# Вывод:
# END
# [1, 2]
# Closing now
📲 Мы в MAX 👉@BookPython

2
Стандартный модуль json имеет интерфейс командной строки, который может быть полезен для форматирования JSON с помощью одного только Python. Этот модуль называется json.tool и используется следующим образом: $ echo '{"a": [], "b": "c"}' | python -m json.tool { "a": [], "b": "c" } 📲 Мы в MAX 👉@BookPython
655
3
Все объекты в Python создаются с помощью вызова метода __new__. Даже если вы определяете свой собственный __new__ для класса, вы должны вызвать super().__new__(...). Можно подумать, что object.__new__ — это базовая реализация, отвечающая за создание всех объектов. Но это не совсем так. Существует несколько таких реализаций, и они несовместимы. Например, у dict есть собственная низкоуровневая реализация __new__, и объекты типов, унаследованных от dict, нельзя создать с помощью object.__new__: In : class D(dict): ...: pass ...: In : class A: ...: pass ...: In : object.__new__(A) Out: <__main__.A at 0x7f200c8902e8> In : object.__new__(D) ... TypeError: object.__new__(D) is not safe, use D.__new__() 📲 Мы в MAX 👉@BookPython
761
4
🚀 Подборка полезных 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 Типичный Сисадмин Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика 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 Обучающие видео, книги по Физике и Математике Вакансии 📌 https://max.ru/progjob Вакансии в IT Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
643
5
Python позволяет перегружать многие разные операторы, и оператор сдвига — один из них. Вот пример того, как можно создать композицию функций с использованием этого оператора. Здесь символы, похожие на стрелки, показывают направление потока данных: from collections import deque from math import sqrt class Compose: def __init__(self): self._functions = deque() def __call__(self, *args, **kwargs): result = None for f in self._functions: result = f(*args, **kwargs) args = [result] kwargs = dict() return result def __rshift__(self, f): self._functions.append(f) return self def __lshift__(self, f): self._functions.appendleft(f) return self compose = Compose sqrt_abs = (compose() << sqrt << abs) sqrt_abs2 = (compose() >> abs >> sqrt) print(sqrt_abs(-4)) # 2.0 print(sqrt_abs2(-4)) # 2.0 Объяснение: << — добавляет функцию в начало цепочки (выполняется первой). >> — добавляет функцию в конец цепочки (выполняется последней). В примере sqrt_abs(-4) сначала берёт abs(-4) → 4, а затем sqrt(4) → 2.0. sqrt_abs2(-4) делает то же самое, но функции добавлены в другом порядке. 📲 Мы в MAX 👉@BookPython
871
6
Класс объекта доступен через атрибут __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 📲 Мы в MAX 👉@BookPython
928
7
В Python числа с плавающей точкой могут иметь значение NaN. Его можно получить с помощью math.nan. NaN не равен ничему, включая самого себя: >>> math.nan == math.nan False Кроме того, объект NaN не является уникальным — можно получить несколько разных объектов NaN из разных источников: >>> float('nan') nan >>> float('nan') is float('nan') False Это означает, что обычно нельзя использовать NaN в качестве ключа словаря: >>> d = {} >>> d[float('nan')] = 1 >>> d[float('nan')] = 2 >>> d {nan: 1, nan: 2} 📲 Мы в MAX 👉@BookPython
936
8
В Python None равен None, поэтому может показаться, что проверку на None можно делать через ==: ES_TAILS = ('s', 'x', 'z', 'ch', 'sh') def make_plural(word, exceptions=None): if exceptions == None: # ← ← ← exceptions = {} if word in exceptions: return exceptions[word] elif any(word.endswith(t) for t in ES_TAILS): return word + 'es' elif word.endswith('y'): return word[0:-1] + 'ies' else: return word + 's' exceptions = dict( mouse='mice', ) print(make_plural('python')) print(make_plural('bash')) print(make_plural('ruby')) print(make_plural('mouse', exceptions=exceptions)) Однако так делать неправильно. Действительно, None равен None, но не только он может быть равен None. Пользовательские объекты тоже могут вернуть True при сравнении с None через ==: class A: def __eq__(self, other): return True print(A() == None) # True print(A() is None) # False Правильный способ проверки на None — использовать is None. 📲 Мы в MAX 👉@BookPython
1 066
9
В Python разные структуры данных объединяются разными способами. Списки используют оператор +: >>> [1, 2] + [2, 3] [1, 2, 2, 3] Кортежи и строки также используют +: >>> (1, 2) + (2, 3) (1, 2, 2, 3) >>> "12" + "23" '1223' Deque (двусторонняя очередь) тоже поддерживает +: >>> deque([1, 2]) + deque([2, 3]) deque([1, 2, 2, 3]) Множества объединяются с помощью оператора |: >>> {1, 2} | {2, 3} {1, 2, 3} Словари объединяются по-другому, и порядок важен, если ключи пересекаются: >>> {**dict(a=1, b=2), **dict(b=3, c=4)} {'a': 1, 'b': 3, 'c': 4} >>> {**dict(b=3, c=4), **dict(a=1, b=2)} {'b': 2, 'c': 4, 'a': 1} Counter (счётчик) можно сложить с помощью +, при этом значения суммируются: >>> Counter(dict(a=1, b=2)) + Counter(dict(b=3, c=4)) Counter({'b': 5, 'c': 4, 'a': 1}) 📲 Мы в MAX 👉@BookPython
1 138
10
Словари, которые используются для хранения атрибутов объектов, не такие же, как те, что вы создаёте с помощью dict, хотя выглядят они абсолютно одинаково: >>> from sys import getsizeof >>> class A: ... pass ... >>> a = dict() >>> b = A().__dict__ >>> type(a) <class 'dict'> >>> type(b) <class 'dict'> >>> a {} >>> b {} >>> getsizeof(a) 240 >>> getsizeof(b) 112 Чтобы уменьшить потребление памяти, словари для __dict__ реализованы иначе. Они разделяют ключи между всеми экземплярами класса A. Однако важно понимать, что b на самом деле не меньше, чем a, - это просто особенность работы getsizeof. 📲 Мы в MAX 👉@BookPython
1 085
11
Если вы хотите измерить время между двумя событиями, следует использовать time.monotonic() вместо time.time(). time.monotonic() никогда не идёт назад, даже если системные часы были изменены: from contextlib import contextmanager import time @contextmanager def timeit(): start = time.monotonic() yield print(time.monotonic() - start) def main(): with timeit(): time.sleep(2) main() 📲 Мы в MAX 👉@BookPython
1 113
12
Декоратор создаёт новый объект (обычно функцию), используя в качестве аргумента другую единственную функцию. Однако иногда хочется задать больше, чем одну функцию. Сделать это напрямую невозможно из-за ограничений синтаксиса Python, но можно использовать небольшой трюк. Возвращаемая функция может содержать ещё один декоратор, который можно повторно применить к дополнительным функциям, добавляя новое поведение. Примерно так работает @property: @property def x(self): return self._x @x.setter def x(self, value): self._x = value Ниже приведён пример того, как можно определить функцию, которая использует дополнительные функции для особых случаев: from functools import wraps def make_case_decorator(func): def case_decorator(*case_decorator_args): def decorator(special_case_func): @wraps(func) def decorated(*args): if case_decorator_args == args: return special_case_func(*args) return func(*args) decorated.case = make_case_decorator(decorated) return decorated return decorator return case_decorator def special_cases(func): @wraps(func) def decorated(*args): return func(*args) decorated.case = make_case_decorator(decorated) return decorated @special_cases def fact(x): return x * fact(x - 1) @fact.case(0) def fact(x): return 1 @fact.case(10) def fact(x): print(f'(сработала оптимизация для {x})') return 3628800 📲 Мы в MAX 👉@BookPython
1 013
13
Ты не можешь изменять переменные замыкания простым присваиванием. Python рассматривает присваивание как определение локальной переменной внутри тела функции и вообще не делает замыкания. Работает нормально, печатает 2: def make_closure(x): def closure(): print(x) return closure make_closure(2)() Вызывает UnboundLocalError: local variable 'x' referenced before assignment: def make_closure(x): def closure(): print(x) x *= 2 print(x) return closure make_closure(2)() Чтобы это заработало, нужно использовать nonlocal. Оно явно сообщает интерпретатору, что присваивание не создает новую локальную переменную, а работает с переменной из замыкания: def make_closure(x): def closure(): nonlocal x print(x) x *= 2 print(x) return closure make_closure(2)() 📲 Мы в MAX 👉@BookPython
941
14
🚀 Подборка полезных 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 Типичный Сисадмин Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика 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 Обучающие видео, книги по Физике и Математике Вакансии 📌 https://max.ru/progjob Вакансии в IT Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
822
15
Любая выполняющаяся корутина asyncio может быть отменена с помощью метода cancel(). В корутину будет выброшено исключение CancelledError, что приведёт к её завершению, а также завершению всех оборачивающих её корутин, если только ошибка не будет перехвачена и подавлена. CancelledError является подклассом Exception, а значит, его можно случайно перехватить конструкцией try ... except Exception, которая предназначена для отлова «любых ошибок». Чтобы безопасно это обработать внутри корутины, приходится писать примерно так: try: await action() except asyncio.CancelledError: raise except Exception: logging.exception('action failed') 📲 Мы в MAX 👉@BookPython
1 090
16
Условное использование менеджеров контекста обычно доставляет неудобства: нельзя просто разместить with внутри блока if, не заключив туда весь блок with. Это часто приводит к дублированию кода: def print_whole_file( *, path: Optional[str] = None, file_obj: Optional[TextIO] = None ): assert path or file_obj if path: with open(path) as f: print(f.read(), end='') else: print(file_obj.read(), end='') Способ борьбы с этой проблемой — использовать ExitStack и вызывать enter_context внутри if: def print_whole_file( *, path: Optional[str] = None, file_obj: Optional[TextIO] = None ): assert path or file_obj with ExitStack() as stack: if path: file_obj = stack.enter_context( open(path) ) print(file_obj.read(), end='') Однако более очевидный способ достичь того же — использовать тривиальные менеджеры контекста, которые ничего не делают, когда они не нужны, вместо «настоящих». Начиная с Python 3.7, их можно получить с помощью contextlib.nullcontext: def print_whole_file( *, path: Optional[str] = None, file_obj: Optional[TextIO] = None ): assert path or file_obj if path: context = open(path) else: context = nullcontext(file_obj) with context as f: print(f.read(), end='') 📲 Мы в MAX 👉@BookPython
1 106
17
В Python функция range() определяет все целые числа в полуоткрытом интервале. То есть range(2, 10) математически означает [2, 10), или, говоря на языке Python: [2, 3, 4, 5, 6, 7, 8, 9]. Несмотря на асимметрию, это не ошибка и не случайность. В этом есть логика: такой подход позволяет "склеивать" два соседних интервала без риска ошибиться на единицу: [a, c) = [a, b) + [b, c) Для сравнения, если бы использовались закрытые интервалы, получалось бы так: [a, c] = [a, b] + [b+1, c] Эта же идея объясняет, почему индексация начинается с нуля: [0, N) содержит ровно N элементов. Эдсгер Дейкстра написал на эту тему отличную статью ещё в 1982 году. 📲 Мы в MAX 👉@BookPython
1 079
18
В списковых включениях (list comprehensions) может быть больше одного цикла for и условия if: In : [(x, y) for x in range(3) for y in range(3)] Out: [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2) ] In : [ (x, y) for x in range(3) for y in range(3) if x != 0 if y != 0 ] Out: [(1, 1), (1, 2), (2, 1), (2, 2)] Кроме того, любое выражение внутри for и if может использовать все переменные, которые были определены ранее: In : [ (x, y) for x in range(3) for y in range(x + 2) if x != y ] Out: [ (0, 1), (1, 0), (1, 2), (2, 0), (2, 1), (2, 3) ] Можно смешивать if и for в любом порядке: In : [ (x, y) for x in range(5) if x % 2 for y in range(x + 2) if x != y ] Out: [ (1, 0), (1, 2), (3, 0), (3, 1), (3, 2), (3, 4) ] 📲 Мы в MAX 👉@BookPython
1 059
19
🚀 Подборка полезных 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 Типичный Сисадмин Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика 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 Обучающие видео, книги по Физике и Математике Вакансии 📌 https://max.ru/progjob Вакансии в IT Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
843
20
Оператор 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. 📲 Мы в MAX 👉@BookPython
810