Найти в Дзене
CyberHub

Фичи Python 3, о которых стоит знать

Оглавление

Много людей начали обновлять свои проекты до третьей версии Python после выхода Python EOL. К сожалению, основная часть кода на Python 3, как на меня, мало отличается от Python 2, так как разработчики не всегда знают, на что способен третий Python. Далее я покажу несколько примеров интересных функций, которые можно использовать только в Python 3.

Все примеры написаны на Python 3.7, и для каждой функции указано минимально необходимую версию Python.

f-строки (3.6+)

Трудно что-либо делать без строк в любом языке программирования, а для полноценной работы нужно иметь структурированный способ обработки строк. Большинство людей, которые пользуются Python, предпочитают использовать метод format.

user = "Jane Doe"
action = "buy"
log_message = 'User {} has logged in and did an action {}.'.format(
user,
action
)
print(log_message)
# User Jane Doe has logged in and did an action buy.

Наряду с format Python 3 предлагает гибкий способ выполнения строчной интерполяции с помощью f-строк. Теперь взгляните на тот же код, но созданный с помощью f-строк:

user = "Jane Doe"
action = "buy"
log_message = f'User {user} has logged in and did an action {action}.'
print(log_message)
# User Jane Doe has logged in and did an action buy.

Pathlib (3.4+)

f-строки удивительные, но некоторые строки, такие как пути к файлам, имеют свои собственные библиотеки, которые делают манипуляции с ними еще проще. Python 3 предлагает pathlib как удобную абстракцию для работы с путями файлов. Если не уверены, надо ли вам использовать pathlib, попробуйте прочитать этот замечательный пост — Почему вам стоит использовать pathlib от Trey Hunner.

from pathlib import Path
root = Path('post_sub_folder')
print(root)
# post_sub_folder
path = root / 'happy_user'
# Make the absolute path
print(path.resolve())
# /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user

Аннотации (3.5+)

Статическая или динамическая типизация является острой темой в разработке программного обеспечения, и почти каждый имеет свое мнение. Я оставляю читателям право решить, им нужна статическая типизация, но я думаю, вы должны хотя бы знать, что Python 3 поддерживает аннотации.

def sentence_has_animal(sentence: str) -> bool:
return "animal" in sentence
sentence_has_animal("Donald had a farm without animals")
# True

Перечисления (enumerations) (3.4+)

Python 3 поддерживает простой способ написания перечислений с помощью класса Enum. Enum является удобным способом инкапсуляции константних списков, чтобы они не были разбросаны по всему коду без структуры.

from enum import Enum, auto
class Monster(Enum):
ZOMBIE = auto()
WARRIOR = auto()
BEAR = auto()

print(Monster.ZOMBIE)
# Monster.ZOMBIE

Перечисление — набор символических имен (членов), привязанных к уникальных, постоянных значений. В перечислении члены можно сравнивать, а сам перечень является интегрированным.

for monster in Monster:
print(monster)
# Monster.ZOMBIE
# Monster.WARRIOR
# Monster.BEAR

Встроенный кэш LRU (3.2+)

Кэше есть практически в любом горизонтальном фрагменте программного и аппаратного обеспечения, которое сейчас используется. Python 3, что делает их очень простыми, выставляя LRU (Least Recently Used) (последний по времени использования) кэш как декоратор под названием lru_cache.

Ниже приведены простую функцию Фибоначчи, что, как известно, выигрывает от кэширования, поскольку она выполняет ту же работу несколько раз путем рекурсии.

import time
def fib(number: int) -> int:
if number == 0: return 0
if number == 1: return 1

return fib(number-1) + fib(number-2)
start = time.time()
fib(40)
print(f'Duration: {time.time() - start}s')
# Duration: 30.684099674224854 s

Теперь мы можем использовать lru_cache для его оптимизации (эта методика оптимизации называется мемоизацией). Время выполнения сокращается от секунд до наносекунд.

from functools import lru_cache
@lru_cache(maxsize=512)
def fib_memoization(number: int) -> int:
if number == 0: return 0
if number == 1: return 1

return fib_memoization(number-1) + fib_memoization(number-2)
start = time.time()
fib_memoization(40)
print(f'Duration: {time.time() - start}s')
# Duration: 6.866455078125 e-05s