Better Programming

Advice for programmers.

Follow publication

Python’s Hidden Gems: 3 Must-Know Functionalities

Erik van de Ven
Better Programming
Published in
4 min readJul 11, 2023

Photo by wu yi on Unsplash

You know Python! Or at least, you think you do. Even though I think I do, and even after eight years of full-time experience, I continue to learn new things. I suppose that’s the remarkable aspect of programming: you never cease to learn.

I’ve worked with data scientists, data engineers, and software engineers of all levels. Some had vast knowledge from which I could continue to learn, while others had some catching up to do.

I have tried to gather and discuss some of the most obscure yet useful functionalities here. I aim to omit basic knowledge, which you could probably just read in the Python tutorial, and focus on more advanced concepts.

Prepare to impress your colleagues and friends with the knowledge you are about to gain.

Enumerations

We have to use these more often. At least, it is one to have in your toolkit. I will give you a small example: let’s say you have a dataclass Car and you would like to have a field that tells you the brand, you would probably want to use Enums for this one. Why? Take a look at the following example:

from dataclasses import dataclass
from enum import Enum, unique


@unique
class CarBrand(Enum):
VOLVO = "volvo"
BMW = "bmw"
VW = "volkswagen"


@dataclass
class Car:
brand: CarBrand


volvo = Car(brand="volvo")

First, let’s break down a little bit of the code:
- Enum This class ensures the members are unique, so you can’t use VOLVO twice with a different value.
- @unique The unique decorator makes sure the values are unique as well. So, you cannot have two members (e.g., VOLVO and BMW) with the same value.

Now, the above code won’t throw an error when using the Python interpreter because Python does not support static typing, and type hints are… hints. But it will throw an error when you use, for example, Mypy, which is definitely worth looking at. Combining enumerations and Mypy will produce more predictable, readable, and less error-prone code. Here’s an example:

$ mypy enumerations.py 
enumerations.py:17: error: Argument "brand" to "Car" has incompatible type "str"; expected "CarBrand" [arg-type]
Found 1 error in 1 file (checked 1 source file)

Mixin

A Mixin is a special kind of multiple inheritance. If you want to provide optional features for a class or use one particular feature in many different classes, you would probably like to use Mixins.

rapper Xzibit laughing. caption: yo dawg, I heard you like mixins. so, I put mixins in your mixins so you can mixin while you’re mixin — quickmeme.com

I have a special example below:

from enum import Enum, unique

@unique
class CarBrand(str, Enum):
VOLVO = "volvo"
BMW = "bmw"
VW = "volkswagen"

message = "I drive a " + CarBrand.VOLVO
print(message)

So, Enum does not contain the special __add__ method, but str does. So, if we didn’t use the Mixin str, the class CarBrand would not have a __add__ method, and we were not able to concatenate it with the string. Try it out. Copy the code, paste it into your interpreter, and try to remove the Mixin.

Inheritance happens from left to right, by the way, so if we have two Mixins and a base class (str is considered the Mixin, Enum is considered the base class), like class CarBrand(str, someOtherClass, Enum), methods are overridden from left to right in case classes contain the same method(s).

Dataclasses

Dataclasses were designed to reduce the typical boilerplate code to create simple data-holding classes. Dataclasses automatically generate common methods, such as __init__(), __repr__(), __eq__(), __hash__(), and __str__() based on the defined class variables. This saves you from writing repetitive code and reduces the chances of errors.

By default, Dataclasses are mutable, but you can make them immutable with the frozen=True parameter. Let’s use the same example again as before:

from dataclasses import dataclass
from enum import Enum, unique


@unique
class CarBrand(Enum):
VOLVO = "volvo"
BMW = "bmw"
VW = "volkswagen"


@dataclass(frozen=True)
class Car:
type: str
brand: CarBrand
mileage: int

volvo = Car(type="318i", brand=CarBrand.BMW, mileage=1000)
volvo.brand = CarBrand.VOLVO

The code above should result in an error, as after instantiation, the dataclass cannot be changed again (as we have given the parameter frozen=True):

Traceback (most recent call last):
File "/home/erik/Development/test-cases/enumerations.py", line 17, in <module>
volvo.brand = CarBrand.VOLVO
^^^^^^^^^^^
File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'brand'

If you still use a Python version ≤ 3.5, you might want to look at attrs (though they’re convinced it is still useful even after the introduction of dataclasses).

Thanks for reading.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Erik van de Ven
Erik van de Ven

Written by Erik van de Ven

Erik is a Senior SE with 15+ years of experience in programming and 8+ years in Python. He ranked the top 9% on Stack Overflow and is a Kaggle Expert.

Responses (1)

Write a response