Некоторый код может выводить интересующие вас данные в stdout, вместо того чтобы предоставлять API, возвращающий строку, пригодную для использования в программе.
Вместо рефакторинга такого кода можно воспользоваться менеджером контекста
Также существует
👉@BookPython
Вместо рефакторинга такого кода можно воспользоваться менеджером контекста
contextlib.redirect_stdout
, который позволяет временно перенаправить stdout в любой объект, поддерживающий файловый интерфейс. В сочетании с io.StringIO
это позволяет сохранить вывод в переменную.
from contextlib import redirect_stdout
from io import StringIO
s = StringIO()
with redirect_stdout(s):
print(42)
print(s.getvalue())
Также существует
contextlib.redirect_stderr
для перенаправления вывода sys.stderr
.👉@BookPython
Каждый вызов
Проблема в том, что любое неожиданное
Последний
Однако это поведение было изменено в Python 3.7. Теперь любое внешнее
Такое же поведение можно включить начиная с Python 3.5 с помощью:
👉@BookPython
next(x)
возвращает следующее значение из итератора x
, если только не возникает исключение. Если это StopIteration
, значит, итератор исчерпан и больше не может возвращать значения. При итерации по генератору это исключение выбрасывается автоматически в конце его тела:
>>> def one_two():
... yield 1
... yield 2
...
>>> i = one_two()
>>> next(i)
1
>>> next(i)
2
>>> next(i)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
StopIteration
автоматически обрабатывается инструментами, которые вызывают next
за вас:
>>> list(one_two())
[1, 2]
Проблема в том, что любое неожиданное
StopIteration
, возникшее внутри генератора, приводит к его молчаливому завершению, а не к выбросу исключения:
def one_two():
yield 1
yield 2
def one_two_repeat(n):
for _ in range(n):
i = one_two()
yield next(i)
yield next(i)
yield next(i)
print(list(one_two_repeat(3)))
Последний
yield
здесь — ошибка: StopIteration
вызывается и прерывает list(...)
. В результате получаем [1, 2]
, что может удивить.Однако это поведение было изменено в Python 3.7. Теперь любое внешнее
StopIteration
, возникшее в генераторе, преобразуется в RuntimeError
:
Traceback (most recent call last):
File "test.py", line 10, in one_two_repeat
yield next(i)
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 12, in <module>
print(list(one_two_repeat(3)))
RuntimeError: generator raised StopIteration
Такое же поведение можно включить начиная с Python 3.5 с помощью:
from __future__ import generator_stop
👉@BookPython
Все объекты в Python создаются с помощью вызова метода
Можно подумать, что
👉@BookPython
__new__
. Даже если вы определяете собственный __new__
для своего класса, вам всё равно нужно вызвать super().__new__(...)
.Можно подумать, что
object.__new__
— это базовая реализация, которая отвечает за создание всех объектов. Но это не совсем так. На самом деле существует несколько таких реализаций, и они несовместимы между собой. Например, у dict
есть собственная низкоуровневая реализация __new__
, и объекты типов, унаследованных от dict
, нельзя создать с помощью object.__new__
:
class D(dict):
pass
class A:
pass
object.__new__(A)
# <__main__.A at 0x7f200c8902e8>
object.__new__(D)
# TypeError: object.__new__(D) is not safe,
# use D.__new__()
👉@BookPython
🚀 Подборка Telegram каналов для программистов
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
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С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 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 академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
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/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
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 программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
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С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 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 академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
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/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
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 программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Telegram
Bash Советы
🚀 Секреты и советы по Bash
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
Чтобы отсортировать словарь по его значениям, используйте функцию
Однако такая функция уже существует в модуле
Вы также можете сортировать только ключи вместо пар ключ-значение:
И снова, эту лямбду можно заменить уже существующим методом:
👉@BookPython
sorted
с пользовательской функцией ключа:
>>> d = dict(a=1, c=3, b=2)
>>> sorted(d.items(), key=lambda item: item[1])
[('a', 1), ('b', 2), ('c', 3)]
Однако такая функция уже существует в модуле
operator
:
>>> from operator import itemgetter
>>> sorted(d.items(), key=itemgetter(1))
[('a', 1), ('b', 2), ('c', 3)]
Вы также можете сортировать только ключи вместо пар ключ-значение:
>>> sorted(d, key=lambda k: d[k])
['a', 'b', 'c']
И снова, эту лямбду можно заменить уже существующим методом:
>>> sorted(d, key=d.get)
['a', 'b', 'c']
👉@BookPython
Популярный способ объявить абстрактный метод в Python — это выбросить исключение
Хотя этот подход довольно распространён и даже поддерживается IDE (например, PyCharm считает такие методы абстрактными), у него есть недостаток: ошибка возникает только при вызове метода, а не при создании экземпляра класса.
Чтобы избежать этой проблемы, используйте модуль
Также важно помнить, что
👉@BookPython
NotImplementedError
:
def human_name(self):
raise NotImplementedError
Хотя этот подход довольно распространён и даже поддерживается IDE (например, PyCharm считает такие методы абстрактными), у него есть недостаток: ошибка возникает только при вызове метода, а не при создании экземпляра класса.
Чтобы избежать этой проблемы, используйте модуль
abc
:
from abc import ABCMeta, abstractmethod
class Service(metaclass=ABCMeta):
@abstractmethod
def human_name(self):
pass
Также важно помнить, что
NotImplemented
— это не то же самое, что NotImplementedError
. NotImplemented
— это специальное значение (как True
и False), а не исключение. Оно используется, например, в специальных методах (__eq__()
, __add__()
и др.), чтобы сообщить Python, что операция не реализована для данного типа, и попытаться вызвать альтернативный метод (например, если a.__add__(b)
возвращает NotImplemented
, Python попробует вызвать b.__radd__(a)).👉@BookPython
collections.defaultdict
позволяет создать словарь, который возвращает значение по умолчанию, если запрашиваемого ключа нет (вместо того чтобы выбрасывать KeyError). Для создания defaultdict
нужно передать не само значение по умолчанию, а фабрику для его создания.Это позволяет создавать словари с потенциально бесконечным уровнем вложенности, благодаря чему можно делать что-то вроде
d[a][b][c]...[z]
.
>>> def infinite_dict():
... return defaultdict(infinite_dict)
...
>>> d = infinite_dict()
>>> d[1][2][3][4] = 10
>>> dict(d[1][2][3][5])
{}
Такое поведение называется "автовивификацией" (autovivification) — термин пришёл из языка Perl.
👉@BookPython
Как упростить работу с аргументами в командной строке с помощью
Раньше для CLI-приложений на Python я использовал
Вот простой пример:
Теперь можно запускать в терминале:
Что круто:
- Автоматически генерируется
- Пишется почти как обычная функция
- Есть автокомплит в оболочках (bash/zsh)
- Поддержка аннотаций типов и валидации "из коробки"
Если ты всё ещё страдаешь с
👉@BookPython
typer
Раньше для CLI-приложений на Python я использовал
argparse
, потом был click
, но недавно полностью перешёл на typer. Это библиотека от автора FastAPI, и она реально 🔥Вот простой пример:
import typer
app = typer.Typer()
@app.command()
def hello(name: str, age: int = 18):
print(f"Привет, {name}! Тебе {age} лет.")
if __name__ == "__main__":
app()
Теперь можно запускать в терминале:
$ python main.py hello Alice --age 30
Привет, Alice! Тебе 30 лет.
Что круто:
- Автоматически генерируется
--help
- Пишется почти как обычная функция
- Есть автокомплит в оболочках (bash/zsh)
- Поддержка аннотаций типов и валидации "из коробки"
Если ты всё ещё страдаешь с
argparse
, рекомендую попробовать typer
. Особенно если ты уже кайфуешь от FastAPI — синтаксис и подход очень похожи.👉@BookPython
Создание объекта в Python включает два ключевых этапа. Сначала вызывается метод
Однако, если
Важно: не следует создавать экземпляры того же класса в
Пример бесконечной рекурсии:
Пример двойного вызова
Правильный способ:
👉@BookPython
__new__
, который создаёт и возвращает новый объект. Затем вызывается метод __init__
для инициализации состояния этого объекта.Однако, если
__new__
возвращает объект, который не является экземпляром исходного класса, метод __init__
не будет вызван. Это связано с тем, что возвращаемый объект, вероятно, уже создан другим классом, и его __init__
уже был выполнен:
class Foo:
def __new__(cls, x):
return dict(x=x)
def __init__(self, x):
print(x) # Никогда не вызывается
print(Foo(0))
Важно: не следует создавать экземпляры того же класса в
__new__
с использованием обычного конструктора (Foo(...)
). Это может привести к двойному вызову __init__
или даже к бесконечной рекурсии.Пример бесконечной рекурсии:
class Foo:
def __new__(cls, x):
return Foo(-x) # Рекурсия
Пример двойного вызова
__init__
:
class Foo:
def __new__(cls, x):
if x < 0:
return Foo(-x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
Правильный способ:
class Foo:
def __new__(cls, x):
if x < 0:
return cls.__new__(cls, -x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
👉@BookPython
Встроенные значения
Это означает, что вы обычно работаете с приближениями, а не с точными значениями:
Модуль
Но и этого может быть недостаточно:
Для абсолютно точных вычислений можно использовать модуль
Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.
👉@BookPython
float
в Python используют оборудование вашего компьютера напрямую, поэтому любое значение представляется внутренне в виде двоичной дроби.Это означает, что вы обычно работаете с приближениями, а не с точными значениями:
>>> format(0.1, '.17f')
'0.10000000000000001'
Модуль
decimal
позволяет использовать десятичную арифметику с произвольной точностью:
>>> from decimal import Decimal
>>> Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
Но и этого может быть недостаточно:
>>> Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
False
Для абсолютно точных вычислений можно использовать модуль
fractions
, который хранит любое число как рациональное:
>>> from fractions import Fraction
>>> Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
True
Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.
👉@BookPython
💡 Как избежать повторения кода с помощью
Как упростить код и избежать дублирования с помощью
Допустим, у нас есть функция
Вместо того чтобы каждый раз писать это явно, можно создать частичную функцию:
Это удобно, если вы хотите предварительно зафиксировать часть аргументов, например:
* логгеры с предустановленным уровнем
* коннекторы с общими параметрами
* команды CLI с типовыми флагами
Таким образом, вы уменьшаете дублирование и делаете код читаемее. А ещё это красивый способ внедрить DI без фреймворков — просто передайте
👉@BookPython
functools.partial
Как упростить код и избежать дублирования с помощью
functools.partial
.Допустим, у нас есть функция
send_email(to, subject, body, is_html=False)
, и мы часто вызываем её с одним и тем же параметром is_html=True
.Вместо того чтобы каждый раз писать это явно, можно создать частичную функцию:
from functools import partial
send_html_email = partial(send_email, is_html=True)
# Теперь можно вызывать проще:
send_html_email("user@example.com", "Привет", "<b>Как дела?</b>")
Это удобно, если вы хотите предварительно зафиксировать часть аргументов, например:
* логгеры с предустановленным уровнем
* коннекторы с общими параметрами
* команды CLI с типовыми флагами
Таким образом, вы уменьшаете дублирование и делаете код читаемее. А ещё это красивый способ внедрить DI без фреймворков — просто передайте
partial
.👉@BookPython
Самый простой способ использовать модуль
Этот глобальный логгер можно настроить с помощью вызова
Однако у
👉@BookPython
logging
— вызывать функции напрямую, без создания объекта логгера:
import logging
logging.error('xxx')
Этот глобальный логгер можно настроить с помощью вызова
logging.basicConfig()
:
import logging
logging.basicConfig(format='-- %(message)s --')
logging.error('xxx') # -- xxx --
Однако у
basicConfig
есть свои ограничения. Во-первых, срабатывает только первый вызов — все последующие игнорируются. Во-вторых, любая функция, записывающая лог, может вызвать basicConfig
, поэтому конфигурацию нужно задавать до любых сообщений:
import logging
logging.error('xxx') # ERROR:root:xxx
logging.basicConfig(format='-- %(message)s --')
logging.error('xxx') # ERROR:root:xxx
👉@BookPython
🚀 Как логировать без боли в Python
Как настроить логирование в Python один раз — и больше к этому не возвращаться.
Обычно начинающие разработчики либо используют
Что мы получаем:
* Удобный формат времени и уровня лога
* Защиту от дублирования логов (если модуль импортируется несколько раз)
* Готовность к масштабированию (можно легко добавить файл-логгер)
Если вы устали от
Пользуетесь ли вы встроенным
👉@BookPython
Как настроить логирование в Python один раз — и больше к этому не возвращаться.
Обычно начинающие разработчики либо используют
print()
, либо подключают logging
, но каждый раз пишут кучу однотипного кода. Я так тоже делал. Но потом вывел себе простую универсальную схему, которую теперь кидаю в каждый новый проект:
import logging
def setup_logger(name: str) -> logging.Logger:
logger = logging.getLogger(name)
if not logger.hasHandlers():
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
logger = setup_logger(__name__)
logger.info("Скрипт стартовал")
Что мы получаем:
* Удобный формат времени и уровня лога
* Защиту от дублирования логов (если модуль импортируется несколько раз)
* Готовность к масштабированию (можно легко добавить файл-логгер)
Если вы устали от
print()
, просто сохраните себе этот сниппет — он сэкономит вам время и нервы.Пользуетесь ли вы встроенным
logging
, или предпочитаете что-то вроде loguru
?👉@BookPython
Python позволяет узнать путь к любому исходному файлу. Внутри файла переменная
Типичное применение этого — определить путь, где находится сам скрипт. Это может быть полезно, например, для поиска других файлов: конфигураций, ресурсов и т.д.
Чтобы получить абсолютный путь из относительного, можно использовать
👉@BookPython
__file__
возвращает относительный путь к нему:
$ cat test/foo.py
print(__file__)
$ python test/foo.py
test/foo.py
Типичное применение этого — определить путь, где находится сам скрипт. Это может быть полезно, например, для поиска других файлов: конфигураций, ресурсов и т.д.
Чтобы получить абсолютный путь из относительного, можно использовать
os.path.abspath
. Поэтому распространённый приём для получения пути к директории скрипта выглядит так:
import os
dir_path = os.path.dirname(
os.path.abspath(__file__)
)
👉@BookPython
Существует два понятия с похожими названиями, которые легко перепутать: переопределение (overriding) и перегрузка (overloading).
Переопределение происходит, когда дочерний класс определяет метод, который уже был реализован в родительском классе, фактически заменяя его. В некоторых языках необходимо явно указывать, что метод переопределяется (например, в C# используется модификатор
Перегрузка, напротив, — это наличие нескольких функций с одним и тем же именем, но разными сигнатурами. Это поддерживается в таких языках, как Java и C++, и часто используется как способ предоставления значений по умолчанию:
Python не поддерживает поиск функций по сигнатурам, только по именам. Вы можете написать код, который явно анализирует типы и количество аргументов, но это обычно выглядит громоздко и не очень красиво:
Если вам нужны подсказки типов для такой реализации, модуль
👉@BookPython
Переопределение происходит, когда дочерний класс определяет метод, который уже был реализован в родительском классе, фактически заменяя его. В некоторых языках необходимо явно указывать, что метод переопределяется (например, в C# используется модификатор
override
), в других — это необязательно (в Java можно, но не обязательно использовать аннотацию @Override
). В Python нет ни обязательного, ни стандартного способа обозначать такие методы (некоторые программисты применяют пользовательский декоратор @override
, который ничего не делает, а служит только для читаемости кода).Перегрузка, напротив, — это наличие нескольких функций с одним и тем же именем, но разными сигнатурами. Это поддерживается в таких языках, как Java и C++, и часто используется как способ предоставления значений по умолчанию:
class Foo {
public static void main(String[] args) {
System.out.println(Hello());
}
public static String Hello() {
return Hello("world");
}
public static String Hello(String name) {
return "Hello, " + name;
}
}
Python не поддерживает поиск функций по сигнатурам, только по именам. Вы можете написать код, который явно анализирует типы и количество аргументов, но это обычно выглядит громоздко и не очень красиво:
def quadrilateral_area(*args):
if len(args) == 4:
quadrilateral = Quadrilateral(*args)
elif len(args) == 1:
quadrilateral = args[0]
else:
raise TypeError()
return quadrilateral.area()
Если вам нужны подсказки типов для такой реализации, модуль
typing
предоставляет декоратор @overload
, который можно использовать следующим образом:
from typing import overload
@overload
def quadrilateral_area(
q: Quadrilateral
) -> float: ...
@overload
def quadrilateral_area(
p1: Point, p2: Point,
p3: Point, p4: Point
) -> float: ...
👉@BookPython
В Python оператор квадратных скобок
Необычность оператора
Что же передаётся в
Пример:
Объект
👉@BookPython
[]
можно переопределить, реализовав магический метод __getitem__
. Это позволяет, например, создать объект, который виртуально содержит бесконечное количество повторяющихся элементов:
class Cycle:
def __init__(self, lst):
self._lst = lst
def __getitem__(self, index):
return self._lst[index % len(self._lst)]
print(Cycle(['a', 'b', 'c'])[100]) # 'b'
Необычность оператора
[]
в Python в том, что он поддерживает особый синтаксис. Его можно использовать не только так: [2]
, но и так: [2:10]
, [2:10:2]
, [2::2]
или даже [:]
. Смысл такой записи — [start:stop:step]
, но в ваших собственных объектах вы можете использовать этот синтаксис как угодно.Что же передаётся в
__getitem__
в таких случаях? Объекты slice
созданы специально для этого.Пример:
class Inspector:
def __getitem__(self, index):
print(index)
Inspector()[1]
# 1
Inspector()[1:2]
# slice(1, 2, None)
Inspector()[1:2:3]
# slice(1, 2, 3)
Inspector()[:]
# slice(None, None, None)
Inspector()[:, 0, :]
# (slice(None, None, None), 0, slice(None, None, None))
Объект
slice
сам по себе ничего не делает — он просто хранит атрибуты start
, stop
и step
:
s = slice(1, 2, 3)
print(s.start) # 1
print(s.stop) # 2
print(s.step) # 3
👉@BookPython
🚀 Подборка Telegram каналов для программистов
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
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С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 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 академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
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/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
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 программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Системное администрирование, DevOps 📌
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
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С
https://t.me/DevLab1C 1С:Предприятие 8
https://t.me/razrab_1C 1C Разработчик
https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://t.me/rabota1C_rus Вакансии для программистов 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 академия.
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python
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/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
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 программиста
https://t.me/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
https://t.me/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Telegram
Bash Советы
🚀 Секреты и советы по Bash
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
Иногда возникает необходимость выполнить участок кода и проигнорировать все возможные исключения. Это оправдано в случае с плагинами, сторонними модулями и другими компонентами, устройство которых вам неизвестно или которым вы не доверяете.
Правильный способ сделать это — использовать конструкцию try с
Голый
👉@BookPython
Правильный способ сделать это — использовать конструкцию try с
except Exception
, а не голый except
:
try:
foreign()
except Exception:
logging.warn('fail', exc_info=True)
Голый
except
эквивалентен except BaseException
. А разница между BaseException
и Exception
в том, что BaseException
включает исключения, которые, как правило, ловить не следует, например, KeyboardInterrupt
.👉@BookPython
В Python имя переменной может состоять из одного символа подчёркивания: _. Хотя такие имена обычно недостаточно описательны и их не стоит использовать, существует по крайней мере три случая, когда _ имеет общепринятое значение.
Во-первых, в интерактивных интерпретаторах Python _ используется для хранения результата последнего выполненного выражения:
Во-вторых, в документации модуля gettext рекомендуется создавать псевдоним для функции gettext() в виде _(), чтобы не загромождать код.
В-третьих, _ используется, когда необходимо придумать имя для значения, которое не представляет интереса:
👉@BookPython
Во-первых, в интерактивных интерпретаторах Python _ используется для хранения результата последнего выполненного выражения:
>>> 2 + 2
4
>>> _
4
Во-вторых, в документации модуля gettext рекомендуется создавать псевдоним для функции gettext() в виде _(), чтобы не загромождать код.
В-третьих, _ используется, когда необходимо придумать имя для значения, которое не представляет интереса:
>>> log_entry = '10:50:24 14234 GET /api/v1/test'
>>> time, _, method, location = log_entry.split()
👉@BookPython
Если вы импортируете модуль, который уже был импортирован, ничего не произойдёт, так как Python отслеживает, какие модули уже были загружены. Все такие модули помещаются в словарь
Если вам действительно нужно перезагрузить модуль, следует использовать функцию
👉@BookPython
sys.modules
:
In : import sys
In : 'sys' in sys.modules.keys()
Out: True
Если вам действительно нужно перезагрузить модуль, следует использовать функцию
importlib.reload(m)
. Здесь m
— это объект модуля, который был успешно импортирован ранее, а не строка с его именем:
In : import importlib
In : importlib.reload(importlib)
Out[5]: <module 'importlib' from '/home/bookpython/.ve/pythonetc/lib/python3.6/importlib/__init__.py'>
👉@BookPython