Python Заметки
رفتن به کانال در Telegram
Интересные заметки и обучающие материалы по Python Контакт: @paulwinex ⚠️ Рекламу на канале не делаю!⚠️ Хештеги для поиска: #tricks #libs #pep #basic #regex #qt #django #2to3 #source #offtop
نمایش بیشتر2 373
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-17 روز
-1130 روز
آرشیو پست ها
2 373
Все знают как красиво написать дату и время с помощью библиотеки datetime:
>>> from datetime import datetime
>>>
>>> dt = datetime.now()
>>> dt.strftime('%Y.%m.%d %H:%I')
'2020.01.08 12:00'
Но мало кто знает, что тоже самое можно сделать и другим способом:
>>> "{:%Y.%m.%d %H:%I}".format(dt)
'2020.01.08 12:00'
Если паттерн хранится отдельно, то можно записать так
>>> date_frmt = '%Y.%m.%d %H:%I'
>>> '{:{}}'.format(dt, date_frmt)
'2020.01.08 12:00'
Хм, а чем это лучше, спросите вы?
1. Удобно писать более комплексные шаблоны
>>> event_name = 'Python-вебинар'
>>> "Сегодня, {:%Y.%m.%d}, ровно в {:%H:%I} мы начинаем {}!".format(dt, dt, event_name)
'Сегодня, 2020.01.08, ровно в 12:00 мы начинаем Python-вебинар!'
(ну да, такие паттерны можно писать и в strftime, если что. Хотя, можете напороться на UnicodeEncodeError даже в Python3!)
Чтобы не повторять аргумент dt делаем форматирование по индексу
"{0:%Y} {0:%H.%I}".format(dt)
Если используем разные даты, то можно сделать форматирование по имени
"{date1:%Y}-{date2:%Y} (current {date1:%Y})".format(date1=dt1, date2=dt2)
2. Форматирование даты находится непосредственно в тексте а не в отдельной переменной, что бывает удобней в некоторых случаях. Например, если текст хранится в базе данных то не нужно гдето отдельно хранить формат дат.
3. Зная про эту фишку, и что реализуется она с помощью magic-метода __format__можно начать писать свои классы с подобным функционалом! Собственно, в классе datetime этот метод просто вызывает уже знакомый метод strftime. Я набросал простой пример с таким поведением, смотрим в гистах 🔗.
2 373
Иногда бывает ситуация когда dev-сервер по какой-либо причине не закрылся и висит в процессах, занимая порт.
Это может быть из-за падения IDE или просто сам забыл погасить и закрыл терминал.
Для таких случаев я набросал простую функцию с командой:
kill_on_port() {
port=$(lsof -t -i:$1)
echo "KILL PROCESS:" $port
sudo kill -9 $port
}
alias killonport="kill_on_port $@"
Код поместить в ~/.bashrc и рестартнуть систему.
Если во время старта dev-сервера получаете ошибку что порт уже занят, просто выполните команду, подставив свой порт.
Bash
killonport 8000Скорее всего бесполезно, если другой процесс назначен на перезапуск вашего dev-сервера в случае падения. Имя команды можете изменить на любое другое. #linux
2 373
Ранее, в посте о главных новшествах Python3, я упоминал про полный переход на unicode. А в конце было сказано:
"Конечно же это НЕ относится к именам переменных и файлов! Только строки и комменты."
На самом деле это было лишь предостережение. Можно создавать имена переменных и модулей на unicode!
То есть мы вполне можем сделать так:
Bash:
$ echo "print('Приветы')" > моймодуль.py
// создали файл с именем на кириллице
>>> import моймодуль ПриветыИли так
>>> Василий = "Василий" >>> Петрович = "Петрович" >>> фулнейм = ' '.join([Василий, Петрович]) >>> print(фулнейм) Василий ПетровичИли так
def сделать_красиво(было):
более_красиво = 100500
стало = было * более_красиво
return стало
Или так
>>> Ψ = 100 >>> Σ = -100 >>> смысл = Ψ + Σ >>> print(смысл) 0Надеюсь не нужно объяснять что смысла в этом ноль и так делать не стоит))) Кстати, это была секретная информация, так что никому! Чтобы и в мыслях не было! 🤐 PS. я поддерживаю русский язык только в комментариях по коду. Конечно, если только вы уверены, что команда разработчиков будет русскоязычной и никак иначе! Это очень помогает разбираться в чужом коде (или в своём через время) Но это крайний случай. #tricks
2 373
Одно из незаметных но приятных изменений в 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
2 373
Поздно писать код, совместимый с 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.py3. Полезные советы Нашел развёрнутую статью про тему 2to3, советую почитать. http://python3porting.com/2to3.html 3. Конвертация Не забываем что в качестве источника для конвертации можно указать директорию. И ВСЕГДА указывайте путь сохранения результата. Пример конвертации пакета
2to3 --output-dir=./py3/package_name -W -n ./package_name#2to3
2 373
Если вы еще не начали переходить на 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.4PY3:
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. Теперь порядок ключей сохраняется! В каком порядке добавляли, в таком порядке они и итерируются. Мелочь, но приятно.
Это далеко не всё, но для начала достаточно 😉
#2to32 373
Сегодня, 01.01.2020, официально завершена поддержка Python2. Старый друг отправляется на пенсию...
