
Python 3 features worth using
- Transfer
Many programmers began to switch from the second version of Python to the third due to the fact that pretty soon support for Python 2 will be discontinued . The author of the article, the translation of which we publish, notes that the bulk of the Python 3-code that he saw, looks like a code with brackets, written in Python 2. According to him, he himself sins something like that . Here he gives examples of some of the great features available only to those who use Python 3. He hopes these features will make life easier for those who learn about them.
All of the examples in this article are written using Python 3.7. The description of each feature contains information about the minimum version of Python necessary for its use.

Without strings, it's hard to write something useful in any programming language. But for effective work with strings, a developer needs convenient tools. Such tools that allow you to operate with complex structures without losing your peace of mind. Most Python developers use the method
Python 3, along with the method
Format strings are a great technology, but special tools have been created to work with some lines, such as file paths, which greatly simplify the manipulation of them. Python 3 has a pathlib module , which is a convenient abstraction for working with file paths. If you are not yet sure of the usefulness of this module for solving your problems, take a look at this material.
Which is better - static or dynamic typing? Perhaps almost every programmer has his own answer to this difficult question. I leave it up to the reader how exactly they typify their programs. But I think it’s good for everyone to at least know that Python 3 supports type annotations .
Python 3 supports, thanks to the class
From the Python 3 documentation , you can find out that an enumeration is a collection of symbolic names (members) tied to unique, immutable values. Members of a single listing can be compared for identity. Enumerations can be bypassed.
Nowadays, caching mechanisms are used in almost all software and hardware systems. Python 3 greatly simplifies caching with the lru_cache decorator , which implements the LRU caching algorithm ( Least Recently Used ).
Below is a function that calculates the Fibonacci numbers. This function is forced many times to perform the same operations during recursive calls. As a result, it turns out that its performance can be improved through caching.
Now we use it
When unpacking iterable objects, you can use variables whose names are preceded by an asterisk. Everything that does not fit into other variables gets into such variables. Thus, in the following example, the variables
Python 3 introduced data classes . They give the programmer a lot of freedom of action. They can be used to reduce the amount of boilerplate code. The fact is that the decorator
Here is the same, but already written using
One way to structure Python code is to use packages (packages are placed in folders that have a file
When using Python 2, each of the folders mentioned in the example should have a file
It should be noted that in fact, everything is not so simple. Namely, in accordance with this official specification, the file
Not all of Python 3’s interesting features are covered in this article, but we hope you find something useful here. Sample code can be found in this repository.
Dear readers! What features of Python 3 would you add to the list here?


Format Strings (3.6+)
Without strings, it's hard to write something useful in any programming language. But for effective work with strings, a developer needs convenient tools. Such tools that allow you to operate with complex structures without losing your peace of mind. Most Python developers use the method
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.
Python 3, along with the method
format
, supports format strings ( f-strings , f-strings). They are a flexible tool for performing various string manipulations. Here's what the previous example looks like, rewritten using format strings: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 module (3.4+)
Format strings are a great technology, but special tools have been created to work with some lines, such as file paths, which greatly simplify the manipulation of them. Python 3 has a pathlib module , which is a convenient abstraction for working with file paths. If you are not yet sure of the usefulness of this module for solving your problems, take a look at this material.
from pathlib import Path
root = Path('post_sub_folder')
print(root)
# post_sub_folder
path = root / 'happy_user'
# Делаем путь абсолютным
print(path.resolve())
# /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user
Type Annotations (3.5+)
Which is better - static or dynamic typing? Perhaps almost every programmer has his own answer to this difficult question. I leave it up to the reader how exactly they typify their programs. But I think it’s good for everyone to at least know that Python 3 supports type annotations .
def sentence_has_animal(sentence: str) -> bool:
return "animal" in sentence
sentence_has_animal("Donald had a farm without animals")
# True
Transfers (3.4+)
Python 3 supports, thanks to the class
Enum
, a simple mechanism for working with enumerations . Enumerations are convenient for storing lists of constants. Constants, otherwise, are randomly scattered in the code.from enum import Enum, auto
class Monster(Enum):
ZOMBIE = auto()
WARRIOR = auto()
BEAR = auto()
print(Monster.ZOMBIE)
# Monster.ZOMBIE
From the Python 3 documentation , you can find out that an enumeration is a collection of symbolic names (members) tied to unique, immutable values. Members of a single listing can be compared for identity. Enumerations can be bypassed.
for monster in Monster:
print(monster)
# Monster.ZOMBIE
# Monster.WARRIOR
# Monster.BEAR
Built-in LRU cache (3.2+)
Nowadays, caching mechanisms are used in almost all software and hardware systems. Python 3 greatly simplifies caching with the lru_cache decorator , which implements the LRU caching algorithm ( Least Recently Used ).
Below is a function that calculates the Fibonacci numbers. This function is forced many times to perform the same operations during recursive calls. As a result, it turns out that its performance can be improved through caching.
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.684099674224854s
Now we use it
lru_cache
to optimize this function (this optimization technique is called memoization ). As a result, the execution time of a function that was previously measured in seconds is now measured in nanoseconds.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.866455078125e-05s
Unpacking iterable objects (3.0+)
When unpacking iterable objects, you can use variables whose names are preceded by an asterisk. Everything that does not fit into other variables gets into such variables. Thus, in the following example, the variables
head
and tail
enter the first and last values from a list generated by the command range(5)
. body
Everything that is between the first and last value gets into the variable .head, *body, tail = range(5)
print(head, body, tail)
# 0 [1, 2, 3] 4
py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split()
print(py)
print(filename)
print(cmds)
# python3.7
# script.py
# ['-n', '5', '-l', '15']
first, _, third, *_ = range(10)
print(first, third)
# 0 2
Data Classes (3.7+)
Python 3 introduced data classes . They give the programmer a lot of freedom of action. They can be used to reduce the amount of boilerplate code. The fact is that the decorator
dataclass
automatically generates special methods, such as __init__()
and __repr__()
. In the official text of the corresponding proposal, they are described as "mutable named tuples with default values." Here is an example of creating a class without using a decorator dataclass
:class Armor:
def __init__(self, armor: float, description: str, level: int = 1):
self.armor = armor
self.level = level
self.description = description
def power(self) -> float:
return self.armor * self.level
armor = Armor(5.2, "Common armor.", 2)
armor.power()
# 10.4
print(armor)
# <__main__.Armor object at 0x7fc4800e2cf8>
Here is the same, but already written using
dataclass
:from dataclasses import dataclass
@dataclass
class Armor:
armor: float
description: str
level: int = 1
def power(self) -> float:
return self.armor * self.level
armor = Armor(5.2, "Common armor.", 2)
armor.power()
# 10.4
print(armor)
# Armor(armor=5.2, description='Common armor.', level=2)
Package folder support without __init__.py file (3.3+)
One way to structure Python code is to use packages (packages are placed in folders that have a file
__init__.py
). Here is an example from the official documentation:sound/ Пакет верхнего уровня
__init__.py Инициализация пакета sound
formats/ Подпакет для преобразования форматов файлов
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Подпакет для звуковых эффектов
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Подпакет для фильтров
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
When using Python 2, each of the folders mentioned in the example should have a file
__init__.py
. Thanks to this file, the folder is perceived as a Python package. In Python 3, with the advent of the Implicit Namespace Packages feature , folders like these are no longer required.sound/ Пакет верхнего уровня
__init__.py Инициализация пакета sound
formats/ Подпакет для преобразования форматов файлов
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Подпакет для звуковых эффектов
echo.py
surround.py
reverse.py
...
filters/ Подпакет для фильтров
equalizer.py
vocoder.py
karaoke.py
...
It should be noted that in fact, everything is not so simple. Namely, in accordance with this official specification, the file
__init__.py
is still needed for regular packages. If you remove it from the folder, the package turns into a so-called namespace package , to which additional restrictions apply.Summary
Not all of Python 3’s interesting features are covered in this article, but we hope you find something useful here. Sample code can be found in this repository.
Dear readers! What features of Python 3 would you add to the list here?
