Когда вы создаете кастомный метод
Пример простого кода:
Проблема возникает, если вы вызываете
Для решения этой проблемы можно использовать декоратор
Теперь код работает корректно:
👉@BookPython
__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, ...)
👉@BookPython
Чтобы читать строки из stdin в Python до версии 3, использовалась функция
В Python 3 функция
Если вы хотите поддерживать код, работающий как в Python 2, так и в Python 3, можно использовать следующий подход:
Популярный модуль
👉@BookPython
raw_input
вместо input
. Проблема с использованием input
заключалась в том, что она выполняла введённую строку как код:
$ echo '[x ** 2 for x in range(10)]' | python2 -c 'print input()'
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
В Python 3 функция
input
просто читает строку, а raw_input
больше не существует.Если вы хотите поддерживать код, работающий как в Python 2, так и в Python 3, можно использовать следующий подход:
from contextlib import suppress
with suppress(NameError):
input = raw_input
Популярный модуль
six
уже реализует этот механизм для вас. Он предоставляет функцию input
, которая просто читает строку, независимо от версии Python.👉@BookPython
Тесты могут требовать временные файлы или директории. Для этого отлично подойдет модуль
Так как временные файлы обычно нужно удалять после использования,
👉@BookPython
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']
👉@BookPython
Нативные значения
Это означает, что в большинстве случаев вы работаете с приближениями, а не с точными значениями:
Модуль
Однако и этого может быть недостаточно:
Для точных вычислений можно использовать
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме.
👉@BookPython
float
в Python используют аппаратные возможности вашего компьютера, поэтому любое значение внутренне представлено в виде двоичной дроби.Это означает, что в большинстве случаев вы работаете с приближениями, а не с точными значениями:
In : format(0.1, '.17f')
Out: '0.10000000000000001'
Модуль
decimal
позволяет использовать десятичную арифметику с произвольной точностью:
In : Decimal(1) / Decimal(3)
Out: Decimal('0.3333333333333333333333333333')
Однако и этого может быть недостаточно:
In [61]: Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
Out[61]: False
Для точных вычислений можно использовать
fractions
, где любое число хранится в виде рационального:
In : Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
Out: True
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме.
👉@BookPython
Подборка Telegram каналов для программистов
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Английский 📌
https://t.me/UchuEnglish Английский с нуля
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Английский 📌
https://t.me/UchuEnglish Английский с нуля
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Соединять части пути к файлу удобно с помощью функции
Это обычно лучше, чем использование строковой конкатенации:
Начиная с Python 3.4, можно использовать класс
👉@BookPython
os.path.join
:
In : dir_path = '/home/vadim/'
In : file_name = 'test.py'
In : os.path.join(dir_path, file_name)
Out: '/home/vadim/test.py'
Это обычно лучше, чем использование строковой конкатенации:
In : dir_path + '/' + file_name
Out: '/home/vadim//test.py'
os.path.join
использует правильный разделитель для текущей платформы (например, \
для Windows) и предотвращает появление двойного разделителя (//
).Начиная с Python 3.4, можно использовать класс
Path
из модуля pathlib
. (С версии Python 3.6 его экземпляры также можно передавать в os.path.join
.) Класс Path
поддерживает объединение путей через оператор /
:
In : Path('/home/vadim/') / Path('test.py')
Out: PosixPath('/home/vadim/test.py')
👉@BookPython
UTF-8 — это кодировка с переменной длиной. Один символ может быть закодирован с использованием одного, двух, трёх или четырёх байтов. Это означает, что нельзя начать чтение строки в кодировке UTF-8 с произвольного байта, так как это может случайно разрушить символ:
Также это означает, что для пропуска первых
Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8:
Как видно, байт является начальным байтом символа, если его вид не совпадает с
Пример использования:
👉@BookPython
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'
👉@BookPython
Иногда вам нужно запустить блок кода с несколькими контекстными менеджерами. Например:
Начиная с Python 2.7 и 3.1, это можно сделать с помощью одного выражения
До этого можно было использовать функцию
Однако в современных версиях Python эта функция устарела и вызывает предупреждение. Вместо неё рекомендуется использовать более продвинутый инструмент —
Это особенно полезно, когда количество контекстных менеджеров неизвестно заранее.
👉@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
Однако в современных версиях 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
]
Это особенно полезно, когда количество контекстных менеджеров неизвестно заранее.
👉@BookPython
Когда корутина asyncio хочет остановиться и взаимодействовать с циклом событий (event loop), она использует
Когда корутина ожидает (
Какое значение возвращает
Почему возникает эта ошибка? Как asyncio понимает, что это вы используете
👉@BookPython
await obj
(или yield from obj
до Python 3.6). Объект obj
должен быть другой корутиной, объектом asyncio.Future
или любым пользовательским объектом, похожим на Future
(любой объект, у которого определен метод __await__
).
async def coroutine():
await another_coroutine()
async def another_coroutine():
future = asyncio.Future()
await future
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Когда корутина ожидает (
await
) другую корутину, вторая начинает выполняться вместо первой. Если она ожидает третью, то выполняется третья. Это продолжается до тех пор, пока какая-нибудь корутина не ожидает объект Future
. Объект Future
фактически возвращает значение, и тогда цикл событий (event loop) получает управление.Какое значение возвращает
Future
? Оно возвращает сам себя. Можете ли вы напрямую использовать yield
для Future
? Нет, это внутренняя деталь, о которой вам обычно не нужно беспокоиться.
class Awaitable:
def __await__(self):
future = asyncio.Future()
yield future
# RuntimeError: yield was used
# instead of yield from in task
async def coroutine():
await Awaitable()
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Почему возникает эта ошибка? Как asyncio понимает, что это вы используете
yield
для Future
, а не сам Future
? Есть простая защита: Future
устанавливает внутренний флаг перед тем, как вернуть управление.👉@BookPython
Если вы хотите передать данные по цепочке вызовов, самый простой способ — использовать аргументы функций.
Однако в некоторых случаях модифицировать все функции в цепочке, чтобы передать новые данные, крайне неудобно. Вместо этого вы можете настроить некоторый контекст, который будет доступен для всех функций по цепочке. Как это можно реализовать технически?
Самое простое решение — глобальная переменная. В Python также можно использовать модули и классы как хранилища контекста, так как они, строго говоря, тоже являются глобальными переменными. Вы, вероятно, делаете это ежедневно, например, для работы с логгерами.
Если ваше приложение многопоточное, обычная глобальная переменная не подойдет, так как она не является потокобезопасной. Одновременно может выполняться несколько цепочек вызовов, и каждая из них нуждается в собственном контексте. Модуль
Но оба этих подхода не подходят для асинхронных приложений, где функции не только вызываются, но и могут быть приостановлены с помощью
Решить эту проблему можно, если цикл событий будет устанавливать и восстанавливать контекст каждый раз, когда он возобновляет выполнение корутины. Модуль
👉@BookPython
Однако в некоторых случаях модифицировать все функции в цепочке, чтобы передать новые данные, крайне неудобно. Вместо этого вы можете настроить некоторый контекст, который будет доступен для всех функций по цепочке. Как это можно реализовать технически?
Самое простое решение — глобальная переменная. В Python также можно использовать модули и классы как хранилища контекста, так как они, строго говоря, тоже являются глобальными переменными. Вы, вероятно, делаете это ежедневно, например, для работы с логгерами.
Если ваше приложение многопоточное, обычная глобальная переменная не подойдет, так как она не является потокобезопасной. Одновременно может выполняться несколько цепочек вызовов, и каждая из них нуждается в собственном контексте. Модуль
threading
решает эту проблему с помощью объекта threading.local()
, который является потокобезопасным. Вы можете хранить данные, просто устанавливая атрибуты, например: threading.local().symbol = '@'
.Но оба этих подхода не подходят для асинхронных приложений, где функции не только вызываются, но и могут быть приостановлены с помощью
await
. Если корутина выполняет await
, цикл событий может переключиться на другую корутину из совершенно другой цепочки вызовов. Это приведет к некорректной работе, как в следующем примере:
import asyncio
import sys
global_symbol = '.'
async def indication(timeout):
while True:
print(global_symbol, end='')
sys.stdout.flush()
await asyncio.sleep(timeout)
async def sleep(t, indication_t, symbol='.'):
loop = asyncio.get_event_loop()
global global_symbol
global_symbol = symbol
loop.create_task(indication(indication_t))
await asyncio.sleep(t)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
sleep(1, 0.1, '0'),
sleep(1, 0.1, 'a'),
sleep(1, 0.1, 'b'),
sleep(1, 0.1, 'c'),
))
Решить эту проблему можно, если цикл событий будет устанавливать и восстанавливать контекст каждый раз, когда он возобновляет выполнение корутины. Модуль
aiotask_context
реализует это, изменяя способ создания задач с помощью loop.set_task_factory
. Пример рабочей версии:
import asyncio
import sys
import aiotask_context as context
async def indication(timeout):
while True:
print(context.get('symbol'), end='')
sys.stdout.flush()
await asyncio.sleep(timeout)
async def sleep(t, indication_t, symbol='.'):
loop = asyncio.get_event_loop()
context.set(key='symbol', value=symbol)
loop.create_task(indication(indication_t))
await asyncio.sleep(t)
loop = asyncio.get_event_loop()
loop.set_task_factory(context.task_factory)
loop.run_until_complete(asyncio.gather(
sleep(1, 0.1, '0'),
sleep(1, 0.1, 'a'),
sleep(1, 0.1, 'b'),
sleep(1, 0.1, 'c'),
))
👉@BookPython
Обе конструкции
Когда вы реализуете метод
PEP 525 позволяет делать то же самое с методом
👉@BookPython
for
и with
могут быть асинхронными. async with
использует магические методы __aenter__
и __aexit__
, а async for
— методы __aiter__
и __anext__
. Все они асинхронные, и внутри них можно использовать await
:
import asyncio
class Sleep:
def __init__(self, t):
self._t = t
async def __aenter__(self):
await asyncio.sleep(self._t / 2)
async def __aexit__(self, *args):
await asyncio.sleep(self._t / 2)
async def main():
async with Sleep(2):
print('*')
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Когда вы реализуете метод
__iter__
, часто вместо написания итератора с методом __next__
используется оператор yield
, который делает метод __iter__
генератором:
class Bracketed:
def __init__(self, data):
self._data = data
def __iter__(self):
for x in self._data:
yield '({})'.format(x)
print(list(Bracketed([1, 2, 3])))
# ['(1)', '(2)', '(3)']
PEP 525 позволяет делать то же самое с методом
__aiter__
. Наличие операторов yield
и await
в теле функции делает её асинхронным генератором. В то время как await
используется для взаимодействия с циклом событий, yield
управляет работой с for
:
import asyncio
class Slow:
def __init__(self, data, t=1):
self._data = data
self._t = t
async def __aiter__(self):
for x in self._data:
await asyncio.sleep(self._t)
yield x
async def main():
async for x in Slow([1, 2, 3]):
print(x)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
👉@BookPython
Рассмотрим следующую иерархию классов:
В каком порядке будет производиться поиск метода
Чтобы исправить эту проблему, Python использует линеаризацию C3 (C3 superclass linearization), алгоритм, который всегда ищет метод сначала во всех дочерних классах, а затем уже в родительских.
Пример вывода MRO (Method Resolution Order):
👉@BookPython
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)
👉@BookPython
Прямой доступ к атрибутам объекта может быть не самой лучшей идеей. Если клиенты взаимодействуют с объектом через методы, вы всегда можете изменить способ обработки каждого запроса, в то время как при прямом доступе к атрибутам это может быть невозможно.
Разные языки решают эту проблему по-разному. В Ruby синтаксически невозможно получить прямой доступ к атрибуту:
Python предлагает решение, которое в некотором роде похоже на то, что есть в Ruby. Вы можете определить свойство (`property`), чтобы
👉@BookPython
Разные языки решают эту проблему по-разному. В 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
👉@BookPython
С версии Python 3.0 выбрасывание исключения внутри блока
Результат выполнения:
Вы также можете добавить
Результат выполнения:
👉@BookPython
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!
👉@BookPython
В Python множества поддерживают операторы сравнения, где
Это означает, что множества частично упорядочены, то есть существуют такие
Некоторые функции, такие как
👉@BookPython
a < b
означает, что a
является подмножеством b
:
>>> {1} < {1, 2}
True
>>> {1} < {2, 3}
False
Это означает, что множества частично упорядочены, то есть существуют такие
a
и b
, что и a < b
, и b < a
— ложны:
>>> {1} < {2, 3}
False
>>> {1} > {2, 3}
False
Некоторые функции, такие как
min
, max
и sorted
, требуют полного порядка, поэтому их применение к списку множеств может дать неожиданные результаты:
>>> min([{1}, {2}])
{1}
>>> min([{2}, {1}])
{2}
👉@BookPython
Иногда вам нужно очистить коллекцию в Python. Вы, вероятно, используете что-то вроде
Правильный способ очистки словаря, множества,
👉@BookPython
d = {}
(для словарей), но на самом деле это не очистка, а создание новой коллекции и выбрасывание старой. Это может сработать для вас, но другие владельцы того же объекта всё ещё будут иметь ссылку на оригинальный.Правильный способ очистки словаря, множества,
deque
и других коллекций — вызвать x.clear()
. 👉@BookPython
Подборка Telegram каналов для программистов
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Английский 📌
https://t.me/UchuEnglish Английский с нуля
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Английский 📌
https://t.me/UchuEnglish Английский с нуля
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Иногда вам может понадобиться проверить синтаксис Python-файла без его запуска. Такая простая проверка может быть полезна, например, в качестве хука перед коммитом или быстрой проверки в рамках непрерывной интеграции (CI).
Прямого способа сделать это нет. Вы можете запустить файл с помощью команды
Тем не менее, стандартная библиотека Python содержит модуль
👉@BookPython
Прямого способа сделать это нет. Вы можете запустить файл с помощью команды
python -m module.py
, что предотвратит выполнение блока if __name__ == '__main__'
. Однако все импорты всё равно будут выполнены, и это может привести к ошибкам, если вы хотите проверить синтаксис в среде, где модуль не может и не должен быть запущен.Тем не менее, стандартная библиотека Python содержит модуль
py_compile
, который генерирует байт-код из исходного файла Python без его выполнения. Это именно то, что нам нужно:
$ python -m py_compile test.c
File "test.c", line 1
int main() {
^
SyntaxError: invalid syntax
👉@BookPython
CPython поддерживает два уровня оптимизации. Вы можете включить их с помощью флагов
- Флаг
- Флаг
Обычная версия скрипта кэшируется в файл
👉@BookPython
-O
и -OO
.- Флаг
-O
устанавливает __debug__
в значение False
и удаляет все операторы assert
из программы. - Флаг
-OO
делает то же самое, а также удаляет строки документации (docstrings).Обычная версия скрипта кэшируется в файл
.pyc
, а оптимизированная версия раньше кэшировалась в файл .pyo
. Однако, начиная с Python 3.5, файлы .pyo
больше не используются. Вместо них, в соответствии с PEP 488, вводятся файлы .opt-1.pyc
и .opt-2.pyc
.👉@BookPython
«Reduce» — это функция высшего порядка, которая рекурсивно обрабатывает итерируемый объект, применяя некоторую операцию к следующему элементу и уже вычисленному значению. Также вы можете знать её под названиями «fold», «inject», «accumulate» или другими.
Использование
В Python функция
Также, если вам нужны простые лямбда-функции, такие как
👉@BookPython
Использование
reduce
с result = result + element
даёт сумму всех элементов, result = min(result, element)
возвращает минимум, а result = element
позволяет получить последний элемент последовательности.В Python функция
reduce
доступна (начиная с Python 3, она была перемещена в functools.reduce
):
from functools import reduce
print(reduce(lambda s, i: s + i, range(10))) # 45
print(reduce(lambda s, i: min(s, i), range(10))) # 0
print(reduce(lambda s, i: i, range(10))) # 9
Также, если вам нужны простые лямбда-функции, такие как
lambda a, b: a + b
, в Python есть модуль operator
, который упрощает их использование:
from operator import add
print(reduce(add, range(10))) # 45
👉@BookPython
Чтобы отсортировать последовательность в Python, используйте
С помощью аргумента
Допустим, нам также нужно, чтобы числа с одинаковым абсолютным значением были расположены в порядке возрастания. В этом случае можно передать кортеж в качестве ключа сравнения:
Это не магия сортировки, а стандартное поведение кортежей в Python:
👉@BookPython
sorted
:
In : sorted([1, -1, 2, -3, 3])
Out: [-3, -1, 1, 2, 3]
С помощью аргумента
key
можно передать функцию, которая будет использоваться для получения ключа сравнения для каждого значения. Например, отсортируем ту же последовательность по абсолютным значениям:
In : sorted([1, -1, 2, -3, 3], key=abs)
Out: [1, -1, 2, -3, 3]
Допустим, нам также нужно, чтобы числа с одинаковым абсолютным значением были расположены в порядке возрастания. В этом случае можно передать кортеж в качестве ключа сравнения:
In : sorted([1, -1, 2, -3, 3], key=lambda x: (abs(x), x))
Out: [-1, 1, 2, -3, 3]
Это не магия сортировки, а стандартное поведение кортежей в Python:
In : (1, 2) == (1, 2)
Out: True
In : (1, 2) > (1, 1)
Out: True
In : (1, 2) < (2, 1)
Out: True
👉@BookPython