Just Python
10.2K subscribers
4.39K photos
11 videos
4.38K links
🐍Простое изучение Python.

Ссылка: @Portal_v_IT

Сотрудничество: @oleginc, @tatiana_inc

Канал на бирже: telega.in/c/justpython_it

РКН: clck.ru/3MnbSc
Download Telegram
Настраиваемый логгер-декоратор

Начнем с примера использования. Так мы не перегружаем внимание внутренней сложностью и повышаем шансы создать удачный интерфейс модуля. На этом принципе основана разработка через тестирование — test-driven development (TTD).

У класса Logger есть метод log_msg(), который можно использовать напрямую внутри функций.

#theory // Just Python
Сложение списков

Не всегда операторы в python ведут себя так, как мы привыкли. Например сложение списков.
Как видно, инструкция 28 в случае + простое сложение, а в случае += — сложение на месте, которое не приводит к созданию нового списка. += в данном случае сопоставим по производительности с list.extend.

#theory // Just Python
Анатомия декоратора в Python

Создадим декоратор @hello_decorator.

Декоратор в Python — функция, которая принимает функцию/класс и возвращает функцию/класс. В примере декоратор hello_decorator() принимает функцию f(), и возвращает функцию wrapper().

#theory // Just Python
Кэширование строк

Стоит отметить, что это очень сильно зависит от интерпретатора Python. Также правила могут измениться в будущем.

Короткие строки в Python кэшируются интерпретатором при инициализации. Это используется для сохранения памяти.

Если вы хотите поэкспериментировать, можете установить Python 2.7 и поиграться с функцией intern(), которая принудительно кэширует строку.

#theory // Just Python
Python оптимизировал создание строки

С помощью dis мы можем посмотреть байт-код программы.

Здесь мы видим, что 'hello' и 'hell' + 'o' ничем не отличается друг от друга, а значит Python поступил по умному и оптимизировал код.

#theory // Just Python
Разница между is и ==

Каждый объект хранится в памяти и имеет свой номер, по которому можно его найти. Этот номер можно получить с помощью функции id().

is занимается сравниванием этих самых адресов. В то время как == вызывает функцию __eq__ и предназначения для сравнения значений класса.

Представьте куб, а потом ещё один такой же. Они одинаковые, но это два абсолютно разных объекта. Также и в программировании.

#theory // Just Python
Булевые операции

x or y — если x правда (True), возвращает x, иначе y.

x and y — если x правда (True), возвращает y, иначе x.

#theory // Just Python
Про переменные и их названия

В python можно встретить переменные по типу name, _name, __name. Но что значат эти подчёркивания перед названием?

_name — индикатор того, что это внутренняя переменная и работать с ней напрямую не стоит. Также при from M import * не импортирует объекты, что начинаются на _.

__name — заменяет имя на _classname__name, где classname — это имя текущего класса с удаленными начальными символами подчеркивания. Используется для определения частных переменных, которыми никто не должен пользоваться.

#theory // Just Python
Что такое @wraps?

Это декоратор из модуля functools, который используется для создания декораторов.

Он обновляет значения __module__, __name__, __doc__ на значение реальной функции, а не декоратора, а также добавляет __wrapped__ для получения доступа к декорируемой функции.

Подробнее можно почитать в документации.

#theory // Just Python
Про copy

В python есть модуль, который называется copy. У него только две функции: copy() и deepcopy().

copy(x) — поверхностно копирует объект и вставляет в него ссылки на объекты, обнаруженные в оригинале.

deepcopy(x) — Создаёт новый объект и рекурсивно вставляет в него копии объектов, которые нашёл в оригинале.

#theory // Just Python
__getattribute__ и __getattr__

Это особые методы, которые вызываются при попытке получить какой-либо атрибут класса. Например, foo.var вызовет __getattribute__, а после, возможно __getattr__.

Отличие между методами только в том, что __getattribute__ используется всегда, а __getattr__ только если атрибут не найден.

#theory // Just Python
Нижние подчёркивание между цифрами

Они никак не влияют на приложение и используются для того, чтобы числа было удобнее считывать при больших значениях.

Таким образом можно разделять десятки, сотни, тысячи и так далее.

#theory // Just Python
Возможности срезов

С помощью срезов мы можем менять элементы списка. Называют это так: «Изменение путем присваивания».

Таким образом мы заменяем элементы внутри этого среза другими из итератора (list, tuple, range).

С их помощью мы также можем добавлять/удалять элементы, опустошать список и многое другое.

Стоит отметить, что в разреженных срезах ([::2]) такое не работает, если длина итератора не равна длине результата среза.

#theory // Just Python
Статические переменные

Это переменная, которая создаётся вместе с типом и существует до закрытия приложения.

Все переменные, что находится внутри класса, но не попадают в ни один метод являются статическими.

#theory // Just Python
Про упаковку и распаковку

Распаковку задаёт переменным значения итерируемого объекта (список, кортеж, строка, генератор).

Упаковка позволяет собрать несколько значений в один список и после работать с ними.

Эти фишки делают код более красивым и элегантным, но стоит знать меру.

#theory // Just Python
Что такое __name__ ?

Каждый раз, когда мы импортируем код, он весь выполняется точно так же, словно мы его просто запустили. Чтобы избежать странного поведения, как на картинке, стоит использовать __name__.

Переменная получает значение '__main__', если программу запустили напрямую (python file.py). Если же файл импортировали как модуль, он получает своё название.

#theory // Just Python
Фабричный метод

Фабричный метод используется как средство предоставления фабричных интерфейсов для создания объектов.

Они позволяют ослабить связи в коде и упростить его: чаще всего он используется, если вам нужно создать объект по какому-то условию.

Таким образом, мы перемещаем большое количество if/elif/else-кода в отдельный метод.

#theory // Just Python
args и kwargs

Бывает ситуации, когда мы не знаем, сколько пользователей передаст параметров функции. В таком случае используют *args и **kwargs.

*argsкортеж со всем позиционными аргументами. Позиционные это те, что передаются по позиции (спасибо, капитан очевидность).

**kwargsсловарь с ключевыми аргументами. Ключевые, как вы поняли, передаются по ключу, то есть key=value.

Эти имена не имеют никакого значения, самое главное — символы звёздочки в начале.

#theory // Just Python
Декораторы

Это функции, которые меняют поведение других функций, не меняя код внутри них.

Сами по себе декораторы составляют вызываемый объект (функция, класс с __call__), который возвращает другой вызываемый объект.

@wraps используется для изменения некоторых значения (__name__, __doc__) на значения функции, с которой мы работаем, а не декоратора.

#theory // Just Python
all и any

all(iterable) — возвращает True, если все элементы в iterable являются True. Документация

any(iterable) — возвращает True, если хотя бы один элемент в iterable является True. Документация

#theory // Just Python
Принцип KISS

«Keep it simple, stupid» означает, что программисту нужно максимально упрощать код, делать его более понятным. Таким образом в разы легче добавить новые фичи в проект, а вы сможете со спокойной душой уйти в отпуск.

Как это — проще? Вам не стоит реализовывать функционал, которые, более вероятно, не будут использовать. Также надо уметь остановиться, добавляя новые уровни абстракции или создавая интерфейсы.

#theory // Just Python