Вам интересно, почему вам следует переходить с Python 3.6 на Python 3.7 или любую другую комбинацию версий? Или вы думаете о поддержке Python 3.5 и хотите знать, каких функций вам следует избегать? Тогда это ваша статья.
Конечно, есть гораздо больше возможностей. Но именно на них я спотыкаюсь чаще всего.
Pyenv
Прежде чем мы начнем вдаваться в подробности, вы должны знать о pyenv. Это очень удобный инструмент, позволяющий легко переключить версию Python. Он загружает их автоматически для вас. Вот как вы это используете:
# See which Python versions are available: $ pyenv install --list # Install one $ pyenv install 3.5.9 # Use one: $ pyenv local 3.5.9
Довольно удобно, что он переключает также инструменты, которые вы устанавливаете вместе с ним. Например, когда вы переключаетесь на 3.5.9, у вас также есть pip
для этой версии.
Python 3.5
Я очень надеюсь, что никто больше не использует версии Python ниже 3.3. Или, не дай бог, хоть Python 2.7 😨.
В Python 3 так много новых функций и улучшений по сравнению с 2.7:
# python2 thinks this is fine, python3 throws an Exception >>> True = False >>> max(['foo', 2]) 'foo' >>> 'foo' > 2 True # Advanced iterable unpacking: a, b, *rest = range(10)
И это еще не все:
- Лучшая обработка юникода 🎉🎉🎉
- Range - это новый xrange (старая функция диапазона была удалена)
- PEP-380:
yield from
вместо перебора конца генератораyield
-ing каждое значение enum
,pathlib
иunittest.mock
(я рассмотрел исправление и имитацию отдельно - это так здорово, что Python теперь включает это 🥳)functools.lru_cache
async
иawait
(источник)
Также имейте в виду, что Python 2.7, Python 3.1 / 3.2 / 3.3 и 3.4 давно подошли к концу. А Python 3.5 достигнет этого в сентябре 2020 года (исходник).
Python 3.6
# Reasonable type annotation syntax >>> from typing import List >>> number : List[int] = [28, 4, 1990] # f-string! >>> bar = 3 >>> f"foo {bar}" 'foo 3' # PEP 515: Underscores in Numeric Literals >>> number = 1_000_000
Список новых возможностей Python 3.6 намного длиннее. Следует отметить одно улучшение: внутреннее представление словарей стало более эффективным, что привело к уменьшению размера памяти на 20%.
Python 3.7
Будущие аннотации очень удобны, когда вы хотите правильно аннотировать свои классы. Это предотвращает оценку аннотаций во время выполнения. Это означает, что если вы хотите вернуть класс Foo в методе этого класса, теперь вы можете это сделать. Раньше приходилось возвращать строку "Foo"
:
from __future__ import annotations class Foo: def __init__(self, bar): self.bar = bar def foo(bar) -> Foo: self.bar = bar + bar return self
- Словари имеют порядок вставки (исходник)
- async и await - зарезервированные ключевые слова (источник)
- PEP-557: Классы данных
Python 3.8
# f-strings for debugging >>> bar = 3 >>> foo = "Hello World" >>> f"{foo=}, {bar=}" "foo='Hello World', bar=3" # Assignment expressions (aka: The Walrus Operator) >>> a = 6 >>> if is_positive := a > 0: ... print("It's positive!") ... else: ... print("It's negative") ... It's positive!
TypedDict тоже неплохой (пример взят из PEP-589):
from typing import TypedDict class Movie(TypedDict): name: str year: int movie: Movie = {'name': 'Blade Runner', 'year': 1982}
Есть еще:
Python 3.9
PEP 584: Словарь Союза
>>> a = {'foo': 'bar', 42: 1337} >>> b = {'x': 'y', 'a': 'b', 'c': 'd', 'foo': 'foo'} >>> a | b {'foo': 'foo', 42: 1337, 'x': 'y', 'a': 'b', 'c': 'd'} >>> b | a {'x': 'y', 'a': 'b', 'c': 'd', 'foo': 'bar', 42: 1337}
Python 3.10
PEP 618 - это график выпуска Python 3.10, который показывает, что он приближается!
Мы будем получать более качественные сообщения об ошибках (PEP 626), и это здорово! Мы также получили улучшения для аннотаций типов 🎉
Слон в комнате структурного сопоставления с образцом (PEP 634, PEP 635, PEP 636). Следующий пример взят из PEP 636:
# Before structural pattern matching command = input("What are you doing next? ") command_parts = command.split() if len(command_parts) == 1: if command_parts[0] == "quit": print("Goodbye!") quit_game() elif command_parts[0] == "look": current_room.describe() elif len(command_parts) == 2: if command_parts[0] == "get": obj = command_parts[1] character.get(obj, current_room) elif command_parts[0] == "go": direction = command_parts[1] current_room = current_room.neighbor(direction) # With structural pattern matching command = input("What are you doing next? ") match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() case ["get", obj]: character.get(obj, current_room) case ["go", direction]: current_room = current_room.neighbor(direction)