Python

Overview

Main page for all things Python. This page serves as a comprehensive reference for Python concepts, features, and best practices.

Getting Started

Installation

Anaconda

An option to install Python is to use Anaconda1. Download the appropriate installation file from https://www.anaconda.com/products/individual. And then run the installer with, e.g., sh ./Anaconda3-2021.11-Linux-x86_64.sh. The installation would typically be under $HOME/anaconda3. There is a page dedicated to configuring and using Anaconda.

Package Management

pip

To install a package from source with pip specify:

pip install --no-binary $PACKAGE

Since requirements files are passed as command-line options to pip, you can also specify it as:

some-package
--no-binary
another-package

Additionally this will also work on setup.py’s install_requires. For instance:

setup(
    install_requires=[
        "some-package==0.0.1 --no-binary"
])

PyOxidizer

An alternative to package Python applications is PyOxidizer.

Language Features

Core Concepts

Operators

Ternary Operator

Ternary operators help reduce the amount of very small if-else blocks. Python does not have a ternary operator like other languages. However, conditionals can be used to the same effect:

y = 7
x = 0 if (y == 1) else 1
print(x)
1
Boolean Operations
and

Unravelling the and boolean operator. The operation can be rewritten as the function u_and:

def u_and(a, b):
   result = a
   if a:
      result = b
   return result

For instance:

a = True ; b = None
print(a and b, u_and(a, b))
a = True ; b = True
print(a and b, u_and(a, b))
a = False ; b = True
print(a and b, u_and(a, b))
None None
True True
False False
or

On the other hand, or can be unravelled as:

def u_or(a, b):
   result = a
   if not a:
      result = b
   return result

As an example:

a = True ; b = None
print(a or b, u_or(a, b))
a = True ; b = True
print(a or b, u_or(a, b))
a = False ; b = True
print(a or b, u_or(a, b))
True True
True True
True True

Control Flow

for … else

for-else blocks allow to capture if a condition was met inside a for-loop. For instance, consider the following for-loop:

locations = ['a', 'b', 'c', 'd', 'f']
treasure = False
for location in locations:
   if location == 'x':
       treasure = True
       break
if not treasure:
   print("X marks the spot, but not found")
X marks the spot, but not found

We can simplify the above logic using a for-else loop:

for location in locations:
   if location == 'x':
       break
else:
   print("X marks the spot, but not found")
X marks the spot, but not found

Input/Output

Modules and Packages

Module System

Missing __init__.py

In versions of Python before 3.3, an __init__.py file was mandatory in order for the interpreter to treat a directory, whether on the filesystem or inside a zipfile, as a Python package directory. This file served as a marker, indicating the presence of importable modules or subpackages, even if it was completely empty and didn’t actually run any code during the package import process.

Starting with Python 3.3, this requirement was relaxed. The interpreter now recognizes any directory on sys.path whose name matches the desired package name as a valid package, regardless of the presence of an __init__.py file. The directory’s modules and subpackages are treated as part of the package namespace.

To illustrate this difference, let’s look at a simple project structure:

project/
    example/
        foo.py

Assume that foo.py has the following content:

print("Hello from ", __name__)

Now, if we set project as the current working directory and try to import example.foo using Python 2.7, we’ll encounter an error:

$ python2 -c "import example.foo" 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named example.foo

However, Python 3.3 and later versions can import the submodule seamlessly:

$ python3 -c "import example.foo"
Hello from  example.foo
Relative Imports

If a relative import is present inside a Python 3 file (e.g. file1) inside a module (e.g. mymod), say:

from .foo import bar   

We will encounter the error:

ImportError: attempted relative import with no known parent package

A possible solution is to include the following in your module’s __init__.py:

import os, sys

sys.path.append(os.path.dirname(os.path.realpath(__file__)))

File System Operations

Path Operations

Get Home Directory

For Python +3.5:

from pathlib import Path

home = str(Path.home())
print(home)
/root
List Files Recursively

For Python +3.5, use glob:

import glob

# root_dir with trailing slash (i.e. /root/dir/)
root_dir = "./_site/"
# Get all HTML files and take first three
files = list(glob.glob(root_dir + '**/*.html', recursive=True))[:3]
for filename in files:
    # Remove the .html extension and the _site prefix
    clean_name = filename.replace(root_dir, '').replace('.html', '')
    print(clean_name)

Date and Time

Timezone Operations

Offset-aware Operations

Let’s say you have a date without timezone (offset naive), for instance:

from datetime import datetime, timezone

ts = datetime.now().replace(tzinfo=None)
print(ts)
2025-07-06 14:23:01.509811

And you want to calculate the \(\delta\) with a datetime which has a time (offset aware). We’ll get an error:

try:
   delta = datetime.now(timezone.utc) - ts
except TypeError as error:
   print(error)
can't subtract offset-naive and offset-aware datetimes

The solution is to add a timezone to the offset naive date. For instance:

ts = datetime.now(timezone.utc)

delta = datetime.now(timezone.utc) - ts
delta
datetime.timedelta(microseconds=24)

Strings

Language Evolution

Python 3.10+

In 2021, the Python steering council accepted the proposal to add a pattern-matching primitive to the language. The proposal consists of PEP634 along with PEP635 and PEP636.

Python 3.9

Python 3.9 changes include:

Footnotes

  1. https://www.anaconda.com/↩︎