Skip to main content

The missing guide to useful Python 3 features

Numerous people started to shift their Python version from 2 to 3 due to Python EOL. One of the most well-known changes is; print function in Python 2 is replaced by the print() function in Python 3. However, parentheses work in Python 2 if a space is added after print keyword because the interpreter evaluates it as an expression. Below, I introduce a few illustrations of amazing features you can find only in Python 3 in the hopes that it will solve your Python problems easily.

All examples are coded in python 3.8.0

f-strings (3.6 +)

It is hard to perform anything in whatever programming language without strings and you expect a structured way to work with strings to stay productive. Most people who use Python prefer to use the format method.

user = “Prince”
action = “coding”
log_message = ‘User {} has logged in and did an action {}.’.format(
user,
action
)
print(log_message)
# User Prince has logged in and did an action coding.

In addition to the format, Python 3 provides a versatile way of interpolating strings via f-strings. It looks like the same code as above using f-strings:

user = “Prince”
action = “coding”
log_message = f’User {user} has logged in and did an action {action}.’
print(log_message)
# User Prince has logged in and did an action coding.

Pathlib (3.4+)

f-strings are incredible, but strings such as file paths have their own libraries that make it easier to manipulate them. As a convenient abstraction for working with file paths, Python 3 provides pathlib. If you’re not sure why you should use pathlib, seek to read this excellent post by Trey Hunner — Why you should use pathlib.

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

Type hinting (3.5+)

Static as against dynamic typing is a hot topic in software engineering and literally everybody has a perspective on it. I’ll let the reader decide when to write types, but I feel you should at least know that Python 3 supports type hints.

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 facilitates a simple way to write enumerations in the Enum class. Enums are a useful way to encapsulate constants lists of constants so they do not appear randomly through the code without much structure.

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

An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over. https://docs.python.org/3/library/enum.html

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

Built-in LRU cache (3.2+)

Almost in every horizontal slice of the software and hardware, we utilize today, caches are present. Python 3 makes it very simple to use by exposing an LRU(Least Recently Used) cache as a decorator called lru cache.

Below is a basic Fibonacci function that we understand will benefit from caching because with a recursion it does the same job several times.

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 can use lru cache to configure it(this optimization technique called memoization). The runtime lowers from seconds to 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

Extended iterable unpacking (3.0+)

I ‘m going to let code discuss here (docs).

 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 provides data classes which have few restrictions and can be used to minimize boilerplate code since the decorator automatically generates special methods like ¼__init__( ) and __repr__( ). They are listed by the official proposal as ‘mutable named tuples with defaults.’

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>

The same implementation of Armor using data classes.

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)

Implicit namespace packages (3.3+)

One way to structure Python code is in packages (folders with an __init__.py file). The following example is provided by Python’s official documentation.

sound/                   Top-level package 
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
effects/ Subpackage for sound effects__init__.py
echo.py
surround.py
reverse.py
filters/ Subpackage for filters__init__.py
equalizer.py
vocoder.py
karaoke.py

In Python 2, every folder above had to have an __init__.py file which turned that folder into a Python package. In Python 3 these files are no longer needed once Implicit Namespace Packages are introduced.

sound/                      Top-level package 
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
effects/ Subpackage for sound effectsecho.py
surround.py
reverse.py
filters/ Subpackage for filtersequalizer.py
vocoder.py
karaoke.py

Note: If you find, it is not as simple as I pointed it out in this section, from the official PEP 420 Specification — __init__.py is still required for regular packages, dropping it from the folder structure will turn it into a native namespace package which comes with additional restrictions, the official docs on native namespace packages show a great example of this, as well as naming all the restrictions.

Underscores in numeric literals (3.6+)

Python 3.6 provides an excellent way to allow reading numerical literals by enabling underscored in the numbers. This can be used to demonstrate, for instance: thousands, hexadecimal and binary numbers.

cost = 10_000
print(f’Cost: {cost}’)
# Cost: 10000
hex_flag = 0xDAFE_FFF8
print(f’Hex flag: {hex_flag}’)
# Hex flag: 3674144760
binary = 0b_0011_1001
print(f’Binary: {binary}’)
# Binary: 57

Python 3.6 provides an excellent way to allow reading numerical literals by enabling the numbers to be underscored. This can be used to demonstrate, for instance: thousands, hexadecimal and binary numbers.

Assignment expressions — “walrus operator” (3.8+)

With Python’s latest version, the walrus operator is introduced, which makes a variable assignment of expression. It can be useful if you intend to refer to the expression later in code and save a line or two in code.

animals = [‘dog’, ‘lion’, ‘bear’, ‘tiger’]for animal in animals:
if (len_animal := len(animal)) > 4:
print(f’The animal “{animal}” has “{len_animal}”, letters!’)
# The animal “tiger” has “5”, letters!

The Ending Note

As almost every internet list, this one is not complete. I hope this information illustrates you at least one Python 3 functionality that wasn’t known previously, and it will allow you to write smoother and more instinctive code.

Comments

  1. This is really a good source of information, I will often follow it to know more information and expand my knowledge, I think everyone should know it, thanks
    Best linux cheat sheet commands service provider.

    ReplyDelete

Post a Comment

Popular posts from this blog

How the Python import system works

How the Python import system works From:  https://tenthousandmeters.com/blog/python-behind-the-scenes-11-how-the-python-import-system-works/ If you ask me to name the most misunderstood aspect of Python, I will answer without a second thought: the Python import system. Just remember how many times you used relative imports and got something like  ImportError: attempted relative import with no known parent package ; or tried to figure out how to structure a project so that all the imports work correctly; or hacked  sys.path  when you couldn't find a better solution. Every Python programmer experienced something like this, and popular StackOverflow questions, such us  Importing files from different folder  (1822 votes),  Relative imports in Python 3  (1064 votes) and  Relative imports for the billionth time  (993 votes), are a good indicator of that. The Python import system doesn't just seem complicated – it is complicated. So even though the  documentation  is really good, it d

On working remote

The last company I worked for, did have an office space, but the code was all on Github, infra on AWS, we tracked issues over Asana and more or less each person had at least one project they could call "their own" (I had a bunch of them ;-)). This worked pretty well. And it gave me a feeling that working remote would not be very different from this. So when we started working on our own startup, we started with working from our homes. It looked great at first. I could now spend more time with Mom and could work at leisure. However, it is not as good as it looks like. At times it just feels you are busy without business, that you had been working, yet didn't achieve much. If you are evaluating working from home and are not sure of how to start, or you already do (then please review and add your views in comments) and feel like you were better off in the office, do read on. Remote work is great. But a physical office is better. So if you can, find yourself a co-working s

Todo lists are overrated

My tasks come from a variety of sources: 1) Tasks from emails  2) Meeting notes with details of people who participated  3) Project related tasks that can have a long format and can be tagged/ delegated  4) Scratchpad for unrefined ideas  5) Detailed documentation for completed technical tasks / ideas  6) FIFO list of high priority small daily tasks No one app has been able to map all the requirements above, and I have tried a lot of them! In my lifetime I’ve tried a dozen todo apps. In the beginning they all seem different, novel and special. Slick UI, shortcuts, tags, subtasks, the list goes on and on. But all our stories were the same: I start using the new app, then after awhile I stop using it. Up until the last week I thought the problem was in myself (you probably think so too). After all, David Allen seems to have figured this shit out. Also there are people leaving long 5 star reviews on every major todo list app, they discuss them on forums, recommend them to friends. But the