Python Заметки
2.3K subscribers
59 photos
2 videos
2 files
213 links
Интересные заметки и обучающие материалы по Python

Контакт: @paulwinex

⚠️ Рекламу на канале не делаю!⚠️

Хештеги для поиска:
#tricks
#libs
#pep
#basic
#regex
#qt
#django
#2to3
#source
#offtop
Download Telegram
Если вы еще не начали переходить на Python3 то сейчас самое время!
Различий очень много. Как внутренние архитектурные решения, невидимые рядовому программисту, так и явные изменения, которые приходится использовать каждый день.

Для тех, кто только начинает знакомиться с 3й версией я собрал самые, на мой взгляд, заметные отличия 3й версии Python.

🔸Unicode по умолчанию
Для тех, кто пишет на Python2, всегда была актуальная проблема использования любых символов вне ASCII таблицы. Это относилось как к строкам в данных, так и просто комментариям по коду.
В Python3 по умолчанию строки это UNICODE, кодировка по умолчанию UTF-8. Теперь можно где угодно в строках использовать символы из кириллицы, таблицы Unicode, иероглифы, смайлы и эмодзи.
Конечно же это не относится к именам переменных и файлов! Только строки и коменты.

🔸Функция print()
Не смотря на то, что теперь приходится писать лишние скобочки, мы получили серьезный апгрейд такой простой, но полезной функции. Если вкратце, то print "объединился" с sys.stdout. Как это работает?

Как не переносить курсор на новую строку после печати?
PY2:
print text,
PY3:
print(text, end='')


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

Форсировать вывод в stdout во время блокирующей операции в консольном приложении.
PY2:
import sys
print text # или sys.stdout.write(text)
sys.stdout.flush()
PY3:
print(text, flush=True)


Кроме того, с помощью аргумента file можно печатать в файл или другой подходящий интерфейс.

🔸Оператор деления
Теперь деление целых чисел не обязательно в результате будет иметь целое число. То есть, если числа int не делятся без остатка то результатом будет float

Как разделить два int и получить float?
PY2:
12/5
>>> 2 # ужасный результат!
12/float(5) # приходится делать так
>>> 2.4
PY3:
12/5
>>> 2.4


Между тем, чтобы работало как раньше, то есть деление без остатка, просто нужно использовать другой оператор:
12//5
>>> 2

🔸Относительный импорт
В Python3 изменили принципы относительного импорта. Теперь стало проще и более предсказуемо. Но об этом лучше подробней и отдельно.

Все перечисленные выше фишки были доступны и в Python2 как бекпорт. То есть можно было активировать этот функционал через модуль __future__. Но когда оно по умолчанию, это сильно удобней)))

🔸 Асинхронное программирование
Теперь в Python3 удобно писать асинхронный код с помощью библиотеки asyncio и аналогичных.

🔸 F-String
Да, в Python добавился новый способ форматирования строки (если не ошибаюсь, уже 5й), но он офигенный!
PY2:
value = 123
string = "Value = {}".format(value)
PY3:
value = 123
string = f"Value = {value}"

🔸Упорядоченный словарь
Нет, я не про OrderedDict, я про обычный dict. Теперь порядок ключей сохраняется! В каком порядке добавляли, в таком порядке они и итерируются. Мелочь, но приятно.

Это далеко не всё, но для начала достаточно 😉


#2to3
Поздно писать код, совместимый с Python2 и Python3 одновременно. Если вы матёрый программист, то, возможно, использовали библиотеку six для создания совместимого кода. Или использовали различные модули автоматизации для преобразования кода из Python2 в совместимый для Python2 и Python3. Например sixer или python-future.

Но это время прошло! Теперь пишем только на 3м Python. Совместимость с версией 2 скоро вовсе не потребуется (кроме отдельных тяжелых случаев поддержки legacy систем, но я надеюсь таких у вас нет или совсем мало)

Скорее всего, у многих появляется вопрос, а что делать с кодом который написан под Python2? Садиться и переписывать? Или хотя бы сделать совместимым с Python3?
Всё зависит от конкретной ситуации. Убедитесь что ваша инфраструктура готова под Python3 прежде чем начать.
Скорее всего пора переписывать и не оглядываться назад!

Но не всё так безнадёжно, в стандартной поставке Python уже давно есть готовый инструмент для автоматизации процесса. Это библиотека lib2to3 и прилагаемый скрипт 2to3.py

С чего начать?

1. Документация
Прежде всего почитайте документацию
https://docs.python.org/3.8/library/2to3.html
А также встроенная справка

для Windows
python C:\python37\Tools\scripts\2to3.py --help
для Linux
2to3-3.7 --help
2to3-2.7 --help
(имена зависят от установленных версий Python)

2. Тест
Прежде чем приступать к ожесточенным конвертациям, обязательно протестируйте весь процесс! Например, чтобы просто посмотреть какие будут изменения в скрипте, запустите команду с флагом --list-fixes

2to3 --list-fixes my_script.py

3. Полезные советы
Нашел развёрнутую статью про тему 2to3, советую почитать.
https://python3porting.com/2to3.html

3. Конвертация
Не забываем что в качестве источника для конвертации можно указать директорию. И ВСЕГДА указывайте путь сохранения результата.
Пример конвертации пакета
2to3 --output-dir=./py3/package_name -W -n ./package_name


#2to3
Одно из незаметных но приятных изменений в Python3, которое не часто упоминается, это проблема Leak of variables.
Относится она к конструкции List Comprehensions, он же генератор списков.
Лучше всего данный фикс показать на примере.

Python2
x = 'some_value'
my_list = [x for x in range(10)]
print x
>>> 9

Python3
x = 'some_value'
my_list = [x for x in range(10)]
print(x)
>>> some_value

Переменная "х" в генераторе списка не затирает глобальную переменную с таким же именем. То есть внутри генератора действуют локальные переменные.
Но стоит помнить, что к обычным циклам это не относится.

Python3
x = 'some_value'
for x in range(10):
pass
print(x)

>>>9

#2to3
В Python2 был необычный способ записать текст в файл с помощью print

>>> print >> open(path, 'w'), 'some text'

Те, кто часто пишет на Python, заметят как не "питонично" выглядит такая запись. Просто какой-то разрыв шаблонов.

Хорошо, что в Python3 этот синтаксис более неактуален. Теперь запись в файл с помощью print выглядит куда более логично:

>>> print('some text', file=open(path, 'w'))

Хотя, я пока не встречал никого кто пишет что-то в файл с помощью print )))

#2to3
Те кто работал с Python2 наверняка помнят, как приходилось поправлять расширение python-файла из переменной ˍˍfileˍˍ чтобы получить именно .py а не .pyc

source_path = os.path.splitext(__file__)[0] + '.py'

В Python3 эта проблема ушла. Всегда возвращается путь именно к исходному файлу .py.
Ну сразу бы так)

#2to3
Всё начиналось с библиотеки six, что означает цифру 6 и является результатом умножения 2*3 (напомню что six это библиотека для написания кода одновременно совместимого для Python 2 и 3).
Но как обычно всегда найдется тот, кому не всё понравится и он напишет свой вариант) В итоге получаем небольшой ряд "числовых" библиотек примерно для одного и того же

https://pypi.org/project/six/
https://pypi.org/project/eight/
https://pypi.org/project/nine/

Выглядит забавно. Я решил проверить, есть ли другие библиотеки с числом в названии, хотя бы до 20. И вот что нашлось:

https://pypi.org/project/one/
https://pypi.org/project/two/
https://pypi.org/project/three/
four - свободно
https://pypi.org/project/five/
https://pypi.org/project/six/
https://pypi.org/project/seven/
https://pypi.org/project/eight/
https://pypi.org/project/nine/
ten - свободно
https://pypi.org/project/eleven/
https://pypi.org/project/twelve/
thirteen - свободно
fourteen - свободно
fifteen - свободно
https://pypi.org/project/sixteen/
seventeen - свободно
nineteen - свободно
twenty - свободно

Назначения у этих проектов, конечно, разные. Есть и заброшенные и популярные. Но места еще есть 😊 Занимаем пока свободно!

PS.
Всех уделал Em Fresh со своей линейкой Python-альбомов😁 (жмакнуть show more)

PPS. Всех читательниц моего канала поздравляю с праздником 🌼 🥳 💐

#offtop #libs #2to3
Что за магический модуль ˍˍfutureˍˍ?

Это имплементация поведения интерпретатора из будущих версий Python.

Разные версии в Python развиваются параллельно. Разработчики ядра Python внедрили модуль ˍˍfutureˍˍ чтобы помочь писать код на старых версиях, но совместимый с новыми версиями интерпретатора. Это помогает более мягко обновить Python, не переписывая всю кодовую базу. Можно сказать что это бекпорт фичей.

Модуль ˍˍfutureˍˍ позволяет "импортировать" функционал Python3 работая с Python2, или использовать фишки из Python3.9 имея в распоряжении только 3.6.

Но что именно делает этот модуль? Если вы откроете исходник, то ничего магического вы там не найдете. Простой класс, несколько флагов и набор инстансов этого класса. По идее, если его импортнуть, ничего поменяться не может, так как там нет никакого исполняемого кода! Только объявления объектов.

А ответ кроется в необходимости делать импорты из ˍˍfutureˍˍ самой первой строкой. Дело в том, что парсер специально заточен на поиск импорта этого модуля в первой строке. Он смотрит что вы там импортнули и специальным образом изменяет поведение интерпретатора, которое в него вшито с помощью бекпортов. Весь дальнейший синтаксический разбор будет с учётом изменений. Именно поэтому импорт ˍˍfutureˍˍ обязательно должен быть первым! Не можем же мы половину модуля исполнять по-старым правилам а вторую половину по-новым)))

#2to3
Что именно мы можем импортнуть из будущих версий? Явно не всё, иначе это была бы, собственно, новая версия. В ˍˍfutureˍˍ выносятся только ключевой функционал, от которого серьезно зависит синтаксис или использование возможностей языка. Самое очевидное это директива print, которая в Python3 стала функцией print().

from __future__ import print_function

Что стало удобней с этой функцией?

🔸 Теперь это функция а не ключевое слово, её можно передать как аргумент или вернуть как результат

def get_logger():
if condition:
return some_handler.write
else:
return print

🔸 С помощью аргументов sep и end можем настроить минимальное форматирование вывода.

sep: разделитель для нескольких объектов
end: последний символ вместо перехода на новую строку

>>> items1 = [1, 2, 3]
>>> items2 = [4, 5, 6]
>>> print(*items1, sep='-', end='-')
>>> print(*items2, sep='-')
1-2-3-4-5-6

🔸 Аргумент flush форсированно пробрасывает буфер аутпута в файл. Полезно для вывода из блокирующих операций. Например, когда вам нужно в stdout выводить прогресс операции, запущенной в subprocess. Если не сделать flush то весь аутпут прилетит только по завершению процесса.

for i in range(100):
print(f'Progress: {i}%', flush=True)
time.sleep(1)

Этот прогресс мы можем отслеживать в реальном времени.
А вот так приходилось делать раньше:

import sys
sys.stdout.write(text + '\n')
sys.stdout.flush()

🔸 Аргумент file позволяет перенаправить вывод в другой поток. Например в файл, сеть или что угодно, что имеет метод write.

print(text, file=open('filename.txt', 'w'))
___________
Ну да, теперь приходится писать лишние скобочки и сложно переучиться на новый лад. Но плюсов, я думаю, больше.

#2to3 #tricks
Вторая по частоте future-функция, которую я использовал, это абсолютный импорт

from __future__ import absolute_import

Что она делает?
Изменения, которые вносит эта инъекция описаны в PEP328
Покажу простой пример.

Допустим, есть такой пакет:

/my_package
/__init__.py
/main.py
/string.py

Смотрим код в my_package/main.py

# main.py
import string

Простой пример готов) Вопрос в том, какой модуль импортируется в данном случае? Есть два варианта:

1. модуль в моём пакете my_package.string
2. стандартный модуль string

И вот тут вступает в дело приоритет импортов. В Python2 порядок следующий: помимо иных источников, раньше ищется модуль внутри текущего пакета, а потом в стандартных библиотеках. Таким образом мы импортнём my_package.string.

Но в Python3 это поведение изменилось. Если мы указываем просто имя пакета, то ищется именно такой модуль, игнорируя имена в текущем пакете. Если мы хотим импортнуть именно подмодуль из нашего пакета то, мы должны теперь явно это указывать.

from my_package import string

или относительный импорт, но с указанием пути относительно текущего модуля main

from . import string

Еще одной неоднозначностью меньше 😎

Подробней про импорты здесь:
https://docs.python.org/3/tutorial/modules.html

#2to3 #pep #basic
Ранее я уже упоминал о другой фишке из ˍˍfutureˍˍ , это оператор деления.

from __future__ import division

Суть проста. Раньше сложность типа данных результата поределялась типом самого сложного операнда.
Например:

int/int => int
int/float => float

В первом случае оба операнда int, значит и результат будет int. Во втором float более сложный тип, поэтому результат будет float.

Если нам требуется получить дробное значение при делении двух int то приходилось форсированно один из операндов конверировать в float.

12/float(5) => float

Но с новой "философией" это не требуется. В Python3 "floor division" заменили на "true division" а старый способ теперь работает через оператор "//".

>>> 3/2
1.5
>>> 3//2
1


То есть теперь деление int на int даёт float если результат не целое число.
В классах теперь доступны методы __floordiv__() и __truediv__() для определения поведения с этими операторами.

Данный переход описан в PEP238.

#pep #2to3 #basic
Какие ассоциации у вас вызывает число 404?
Сразу вспоминается ошибка 404 Not Found (не найдено).

Именно такой номер имеет PEP 404 Python 2.8 Un-release Schedule для несуществующего релиза Python 2.8.

В нём нам сообщают что релиз 2.8 никогда не выйдет и даются советы как перейти на ветку 3.х.

#pep #2to3
https://github.com/davvid/wg-python3/blob/guidelines/deliverables/guidelines.rst

Гайдлайн по кодингу на Python с учётом версии 2 и 3.
Полезно почитать тем, кто всё еще переходит на Python3.

#2to3
­Уже полтора года как Python2 отправился на пенсию.
Как идёт процесс перехода на 3ю ветку?
В вебе всё более менее нормально. Django начиная с 2.0 и недавно вышедший Flask 2.0 официально больше не поддерживают Python 2.
На странице Qt for Python вторая ветка пропала из таблицы поддерживаемых версий. Теперь минимальная версия 3.8.

Но меня больше интересует готовность CG-софта. Я предполагал, что период перехода займёт от 3 до 5 лет. При том что резко, как с web, перескочить не получится и какое-то время придётся поддерживать обе ветки (как это сделали с Houdini и Maya). А ведь переделывать там ой как много.
Но, к счастью, процесс идёт достаточно бодро! Судя по этой статистике три четверти приложений уже на Ру3!😊 Остальные догоняют.

Надеюсь план по переходу на 3й Python будет завершён к концу 2021 года.

#2to3
Что-нибудь слышали про Лабораторию динамики флуоресценции?
Если не интересуетесь конкретно этой наукой то здесь вам ловить нечего. Кроме одного момента! Сотрудник лаборатории Christoph Gohlke поддерживает неофициальную библиотеку бинарников для Python под Windows. Большая коллекция скомпиленных библиотек под разные версии Python.

Именно здесь я долгое время качал старую версию PySide под Python2 и OpenImageIO, пока не потребовалось собрать её иначе.

В общем, всем тем кто на Windows, советую страничку в закладки. Также будет полезно тем кто еще на Python2.
Кстати, эта коллекция всё еще обновляется.

#libs #2to3
А вы ждёте выхода Python 4? Ну зря ждёте😭
По словам Гвидо, ему хватило проблем с переходом со 2го на 3й)
Лучше постепенно развивать имеющийся функционал с полной совместимостью кодовой базы чем делать такие резкие изменения.
Велика вероятность что выше 3 мажорная версия более не поднимется.

А как же обещания про невероятные ускорения в Python 4? Очевидно, что теперь они все будут добавляться в 3ю ветку.
Вот здесь можно почитать про планы ускорения
где Гвидо обещает скорость уже в 3.11 и х5 через 4 года!

Здесь можно посмотреть следующие шаги по оптимизации.

#offtop #2to3
Помогая окружающим, лучше всего делать то, что умеешь делать лучше всего! Поэтому я решил сделать все свои курсы бесплатными и выложить в открытый доступ❗️

Был период в моей жизни, когда эти курсы помогли мне выжить. Теперь, я надеюсь, они помогут кому-то еще.

Спасибо всем, кто покупал мои курсы, даже если потом не смотрел 😁

Навыки программирования нынче оцениваются достаточно высоко, это шанс найти работу с зарплатой повыше, попросить повышения или просто улучшить свою продуктивность с помощью кодинга! Так что пользуйтесь 😉

Сразу скажу, курсы не свежие, записанны в 2014-2015 гг. Некоторая информация устарела но примерно на ±90% всё еще актуально.

Какие курсы доступны:

▫️ Advanced Python Scripting
Это компиляция из 3х курсов начального, среднего и высокого уровня сложности. С нуля до создания собственных десктоп-приложений.

▫️ Python for Maya
Курс для Python-разработчиков в Maya. Да, Autodesk ушел от нас, но скорее всего, вернётся)

▫️ Python for Nuke
Курс для Python-разработчиков в Nuke.

▫️ Python for Houdini
Курс для Python-разработчиков в Houdini. Самый отстающий в актуальности курс, так как Houdini развивается и меняется очень стремительно и кардинально. Тем не менее, 80-90% курса актуальна.

▫️ Houdini Fundamentals
Курс поможет познакомиться с крутым софтом для 3D графики — SideFX Houdini. Записан на версии 16. Рассчитан на нулевой уровень подготовки.
На этот раз курс не про Python, только про сам софт.

Все Python-курсы записаны с Python2, вам потребуется изучить особенности перехода на версию Python3, о чем я не раз говорил на своём канале. Ищите по хэштегу #2to3

💬 Остальные подробности в комментах

Переходите на сайт школы и выбирайте курс:
➡️ https://cgninjas.ru/ ⬅️

📌 @pythonotes

#offtop
37👍19🥰1😁1