Guides Guide 7 Reference

Built-in Functions

All 71 names Python gives you for free. Grouped by the job they do, with every parameter explained and several ways to call each one.

These names live in the builtins module, which Python loads into every scope before your first line runs. No import needed, ever. This page is a working reference. Each entry gives the signature, what each parameter means, three or four real call forms, and the trap that catches people.

Some of these are classes, not functions. int, list, str, type and friends are types. You call them and get an instance. The docs list them here because you use them exactly like functions. A trailing / in a signature means the parameters before it are positional only. You cannot pass them by name.

Contents

  1. The 20 you use daily
  2. Math and numbers (7)
  3. Number types and bases (7)
  4. Text and characters (8)
  5. Build containers (10)
  6. Loop and reshape data (13)
  7. Inspect objects (13)
  8. Write classes (4)
  9. See the current scope (2)
  10. Run code from text (4)
  11. Files (1)
  12. Debug and help (2)
  13. Pairs people confuse
  14. Looks built-in, is not

The 20 you use daily

If you learn nothing else, learn these. They cover almost every line of real Python.

lenrangeenumeratezip sortedsumminmax intstrfloatlist dictsettupleprint isinstanceanyallopen
The one habit that matters. Built-ins run in C. A loop you write runs in Python. sum(xs), max(xs) and any(...) beat the hand-written loop on speed and on readability. Reach for the built-in first.

Math and numbers

Seven functions. Arithmetic that is common enough to not need import math.

abs(x, /)

Distance from zero. Drops the minus sign.

abs(-5)            # 5
abs(-2.5)          # 2.5
abs(3 + 4j)        # 5.0   the magnitude, not a part
sorted(xs, key=abs)  # sort by size, ignoring sign

Trap. abs(-2**63) is fine in Python. Ints have no fixed width, so there is no overflow.

divmod(a, b, /)

Floor division and remainder in one call. Returns a 2-tuple.

divmod(7, 2)             # (3, 1)      same as (7 // 2, 7 % 2)
divmod(-7, 2)            # (-4, 1)     floor, so it rounds down
hours, mins = divmod(135, 60)   # (2, 15)
divmod(7.5, 2)           # (3.0, 1.5)  floats work too

Use it for. Time splits, base conversion, and grid coordinates from a flat index.

max(iterable, *, key=None, default) or max(a, b, *args, key=None)

The largest item. Two call forms: one iterable, or several separate values.

max([3, 9, 1])                       # 9
max(3, 9, 1)                         # 9      separate args
max(words, key=len)                  # longest word
max(people, key=lambda p: p.age)     # oldest person object
max([], default=0)                   # 0      no exception
max(counts, key=counts.get)          # key with the biggest value

Trap. key and default are keyword only. max(xs, len) is a silent bug: it compares the list to the function.

min(iterable, *, key=None, default) or min(a, b, *args, key=None)

The smallest item. Same rules as max in every way.

min([3, 9, 1])                       # 1
min(a, b)                            # clamp lower bound
min(points, key=lambda p: p[0]**2 + p[1]**2)   # closest to origin
min(intervals, key=lambda iv: iv[1]) # earliest end time

Idiom. max(low, min(high, x)) clamps x into a range.

pow(base, exp, mod=None)

Raise to a power. With three arguments it does fast modular exponentiation.

pow(2, 10)             # 1024        same as 2 ** 10
pow(2, -1)             # 0.5         negative exponent gives a float
pow(2, 100, 1000)      # 376         fast, never builds the huge number
pow(3, -1, 7)          # 5           modular inverse, Python 3.8+

Why three args. 2**100 % 1000 builds a 31-digit number first. pow(2, 100, 1000) never does. This is the crypto and hashing path.

round(number, ndigits=None)

Round to a given number of decimal places.

round(3.567)           # 4      an int, not a float
round(3.567, 2)        # 3.57
round(1234, -2)        # 1200   round to the nearest hundred
round(2.5)             # 2      banker's rounding, see below
round(0.5)             # 0

Trap. Python rounds halves to the even number. So round(2.5) is 2 and round(3.5) is 4. This is deliberate and reduces bias. For money, use decimal.Decimal with ROUND_HALF_UP.

sum(iterable, /, start=0)

Add up the items, left to right.

sum([1, 2, 3])              # 6
sum([1, 2, 3], 100)         # 106
sum(x*x for x in nums)      # generator, no temp list
sum(1 for x in nums if x > 0)   # count matches
sum([[1], [2]], [])         # [1, 2]  works, but O(n^2). Use itertools.chain

Trap. sum refuses strings on purpose. Use "".join(parts). For floats needing precision, use math.fsum.

Number types and bases

Seven functions. Convert between number types, and between an int and its text form in another base.

int(x=0) or int(x, base=10)

A whole number. Truncates floats toward zero, or parses text.

int('42')            # 42
int(3.99)            # 3       truncates, never rounds
int(-3.99)           # -3      toward zero, not down
int('ff', 16)        # 255
int('1010', 2)       # 10
int('0x1f', 0)       # 31      base guessed from the prefix
int('  7 ')          # 7       surrounding spaces are fine

Trap. int('3.5') raises ValueError. Go through float first: int(float('3.5')).

float(x=0.0, /)

A 64-bit decimal number.

float('3.5')         # 3.5
float(7)             # 7.0
float('1e-3')        # 0.001
float('inf')         # inf     handy as a starting "worst" value
float('nan') == float('nan')   # False. Use math.isnan

Trap. 0.1 + 0.2 != 0.3. That is binary floating point, not a Python bug. Compare with math.isclose.

complex(real=0, imag=0) or complex(string)

A number with a real and an imaginary part.

complex(1, 2)        # (1+2j)
complex('1+2j')      # (1+2j)   note: no spaces allowed inside
z = 3 + 4j
z.real, z.imag       # (3.0, 4.0)
abs(z)               # 5.0

Handy for. 2D grid problems. One complex number holds x and y, and adding does the move.

bool(x=False, /)

True or False. Applies Python's truthiness rules.

bool([])             # False
bool([0])            # True    non-empty list, contents ignored
bool('False')        # True    any non-empty string is true
bool(0.0)            # False
True + True          # 2       bool is a subclass of int
sum(flags)           # counts the True values

Style. Write if items: not if len(items) > 0:. Both work; the first is idiomatic.

bin(x, /)

The binary text form of an int, with a 0b prefix.

bin(10)                    # '0b1010'
bin(10)[2:]                # '1010'    drop the prefix
format(10, '08b')          # '00001010' padded, no prefix
bin(-5)                    # '-0b101'  sign, not two's complement
bin(x).count('1')          # popcount. Or x.bit_count() in 3.10+

hex(x, /)

The hexadecimal text form of an int, with a 0x prefix.

hex(255)                   # '0xff'
hex(255)[2:]               # 'ff'
format(255, '04X')         # '00FF'   padded and upper case
int(hex(255), 16)          # 255      round trip
bytes([255, 0]).hex()      # 'ff00'   for byte strings

oct(x, /)

The octal text form of an int, with a 0o prefix.

oct(8)                     # '0o10'
oct(0o755)                 # '0o755'
os.chmod(path, 0o644)      # the one place you still meet octal
int('755', 8)              # 493

Text and characters

Eight functions. Make text, show text, and move between a character and its code point.

str(object='') or str(bytes, encoding, errors='strict')

Text. The friendly form of a value, meant for humans.

str(42)                          # '42'
str([1, 2])                      # '[1, 2]'
str(b'hi', 'utf-8')              # 'hi'   same as b'hi'.decode()
str(b'\xff', 'utf-8', 'replace') # a placeholder char, no crash
f'{value}'                       # calls str() under the hood

repr(obj, /)

The unambiguous form of a value, meant for developers. Should look like valid Python.

repr('a')            # "'a'"    quotes are visible
str('a')             # 'a'      quotes are not
repr('a\nb')         # "'a\\nb'"  escapes show up
print(f'{name!r}')   # !r means "use repr here"

Use it when. Debugging whitespace or type confusion. repr shows the difference between 1 and '1'; str hides it.

ascii(obj, /)

Like repr, but escapes every non-ASCII character.

ascii('café')        # "'caf\\xe9'"
repr('café')         # "'café'"
ascii('日本')         # "'\\u65e5\\u672c'"

Use it when. A log file or terminal cannot handle Unicode, or you need to see exactly which code points are in a string.

format(value, format_spec='')

Apply one format spec to one value. The engine behind f-strings.

format(3.14159, '.2f')     # '3.14'
format(1234567, ',')       # '1,234,567'
format(0.256, '.1%')       # '25.6%'
format('hi', '>10')        # '        hi'  right aligned
format(255, '#06x')        # '0x00ff'
f'{3.14159:.2f}'           # same thing, preferred in normal code

When to call it directly. When the spec itself is a variable: format(x, spec).

chr(i, /)

The character for a Unicode code point.

chr(65)                          # 'A'
chr(97)                          # 'a'
chr(ord('a') + 1)                # 'b'   next letter
[chr(ord('a') + i) for i in range(26)]   # the alphabet

ord(c, /)

The code point for one character. The inverse of chr.

ord('A')                   # 65
ord('a') - ord('A')        # 32    case gap
counts[ord(ch) - ord('a')] += 1    # 26-slot array instead of a dict

Trap. ord('ab') raises TypeError. One character only.

print(*objects, sep=' ', end='\n', file=None, flush=False)

Write values to a stream, with separators.

print('a', 'b')                        # a b
print('a', 'b', sep='-')               # a-b
print('loading', end='')               # no newline
print(*my_list, sep='\n')              # one item per line
print('error', file=sys.stderr)        # to the error stream
print(f'{pct}%', end='\r', flush=True) # a live-updating line

input(prompt='')

Read one line from standard input. Always returns a string.

name = input('Name: ')             # always a str
age = int(input('Age: '))          # convert yourself
n, m = map(int, input().split())   # two ints on one line

Trap. The trailing newline is stripped, but other whitespace is not. And input() raises EOFError at end of file, so guard it in scripts that read piped input.

Build containers

Ten functions. Every core data structure, plus the two lazy ones.

list(iterable=(), /)

An ordered sequence you can change.

list()                     # []
list('abc')                # ['a', 'b', 'c']
list(range(3))             # [0, 1, 2]
list({'a': 1})             # ['a']   dicts iterate over keys
list(zip(xs, ys))          # drain an iterator into memory
copy = list(original)      # a shallow copy

Trap. list(gen) drains the generator. A second call gives [].

tuple(iterable=(), /)

An ordered sequence you cannot change. Hashable if its items are.

tuple([1, 2])              # (1, 2)
tuple('ab')                # ('a', 'b')
(1,)                       # a 1-tuple. The comma makes it, not the brackets
seen.add(tuple(row))       # lists cannot go in a set. Tuples can
cache[(x, y)] = value      # tuples make fine dict keys

dict(**kwargs) or dict(mapping) or dict(pairs)

A key to value map. Keeps insertion order since Python 3.7.

dict(a=1, b=2)                   # {'a': 1, 'b': 2}
dict([('a', 1), ('b', 2)])       # same
dict(zip(keys, values))          # the pairing idiom
dict.fromkeys('abc', 0)          # {'a': 0, 'b': 0, 'c': 0}
{**base, **overrides}            # merge, right side wins

Trap. Keys must be hashable, so no lists. And dict(a=1) cannot make a key with a space or a dash in it.

set(iterable=(), /)

An unordered bag of unique, hashable items. O(1) membership tests.

set([1, 1, 2])             # {1, 2}
set()                      # the empty set. {} is an empty DICT
set('hello')               # {'h', 'e', 'l', 'o'}
a | b, a & b, a - b        # union, intersection, difference
len(set(xs)) != len(xs)    # "has duplicates" in one line

Why it matters. Swapping x in a_list for x in a_set is the single most common way to turn O(n²) into O(n).

frozenset(iterable=(), /)

A set you cannot change. Because it is immutable, it is hashable.

frozenset([1, 1, 2])                 # frozenset({1, 2})
groups = {frozenset({'a','b'}): 1}   # a set used as a dict key
seen.add(frozenset(members))         # dedupe unordered groups

Use it for. Anagram grouping, graph edge sets, and any cache key where order should not matter.

bytes(source=b'') or bytes(str, encoding, errors)

A fixed sequence of integers from 0 to 255. Raw binary data.

bytes([65, 66])            # b'AB'
bytes(3)                   # b'\x00\x00\x00'
bytes('hi', 'utf-8')       # b'hi'   same as 'hi'.encode()
b'AB'[0]                   # 65      indexing gives an INT
b'AB'[0:1]                 # b'A'    slicing gives bytes

Trap. Indexing a bytes object gives an int, not a one-byte string. Slice instead if you want bytes back.

bytearray(source=b'') or bytearray(str, encoding, errors)

The same as bytes, but you can change it in place.

buf = bytearray(b'hi')
buf[0] = 72                # bytearray(b'Hi')
buf.extend(b' there')      # grows in place, no copy
buf += b'!'
bytes(buf)                 # freeze it back

Use it for. Building a binary message piece by piece. Repeated bytes + bytes is O(n²); a bytearray is amortised O(1).

memoryview(object)

A window onto another object's bytes. Slicing it copies nothing.

mv = memoryview(b'abcdef')
mv[0]                      # 97
bytes(mv[1:3])             # b'bc'   the slice itself was free
data = bytearray(1_000_000)
chunk = memoryview(data)[500:600]   # no 1 MB copy
chunk[0] = 65              # writes straight into `data`

Use it for. Parsing large buffers without copying. data[500:600] on a bytearray copies; the memoryview version does not.

range(stop) or range(start, stop, step=1)

A lazy sequence of evenly spaced ints. Stores only three numbers.

range(3)                   # 0, 1, 2
range(2, 5)                # 2, 3, 4
range(0, 10, 2)            # 0, 2, 4, 6, 8
range(5, 0, -1)            # 5, 4, 3, 2, 1
len(range(10**18))         # instant. Nothing is built
10**17 in range(10**18)    # also instant. It does the maths

Not a generator. A range is re-iterable, supports len, indexing and slicing, and never runs out. It is a real sequence.

slice(stop) or slice(start, stop, step=None)

A reusable slice object. What a[1:5:2] builds behind the scenes.

FIRST_NAME = slice(0, 10)        # name the columns once
record[FIRST_NAME]               # readable at every use site
[1,2,3,4][slice(None, None, 2)]  # [1, 3]   same as [::2]
s.indices(len(seq))              # (start, stop, step) clamped to the length

Use it for. Fixed-width record parsing, and inside __getitem__ when you handle both ints and slices.

Loop and reshape data

Thirteen functions. The largest group, and the one that shapes how Python code reads.

len(s, /)

How many items. O(1) for every built-in type.

len('hello')               # 5
len({'a': 1})              # 1     pairs, not keys plus values
len(range(10**9))          # instant
len(x for x in xs)         # TypeError. Generators have no length

Trap. No length on generators, files or map objects. Convert with list() first, or use sum(1 for _ in it).

iter(object) or iter(callable, sentinel)

Get an iterator. The second form calls a function until it returns a stop value.

it = iter([1, 2, 3])
next(it)                                  # 1
for chunk in iter(lambda: f.read(4096), b''):
    process(chunk)                        # read a file in blocks
for line in iter(input, 'quit'):
    handle(line)                          # read until the user types quit

The pairing idiom. it = iter(xs); list(zip(it, it)) chunks a flat list into pairs.

aiter(async_iterable, /)

The async version of iter. Python 3.10+.

async def consume(stream):
    ait = aiter(stream)        # what `async for` calls for you
    async for item in stream:  # the normal way to consume one
        handle(item)

anext(async_iterator, default)

The async version of next. Returns an awaitable. Python 3.10+.

async def peek(ait):
    first = await anext(ait)         # raises StopAsyncIteration when empty
    safe = await anext(ait, None)    # None instead of an error
    return first, safe

Trap. You must await it. Forgetting gives you a coroutine object, not a value.

enumerate(iterable, start=0)

Pair each item with a running count. Lazy.

list(enumerate('ab'))            # [(0, 'a'), (1, 'b')]
list(enumerate('ab', 1))         # [(1, 'a'), (2, 'b')]
for i, ch in enumerate(s):
    ...
for i, (a, b) in enumerate(pairs):   # nested unpacking works
    ...

Style. Never write for i in range(len(xs)). Use enumerate. Reviewers notice.

zip(*iterables, strict=False)

Walk several iterables together, yielding tuples. Lazy.

list(zip([1,2], 'ab'))               # [(1,'a'), (2,'b')]
list(zip([1,2,3], 'ab'))             # [(1,'a'), (2,'b')]  silently short
list(zip(xs, ys, strict=True))       # raises on a length mismatch
dict(zip(keys, values))              # build a dict from two lists
list(zip(*matrix))                   # transpose rows and columns
zip(xs, xs[1:])                      # every neighbouring pair

Trap. Without strict=True, zip stops at the shortest input. That hides bugs. Use itertools.zip_longest when you want padding instead.

map(function, *iterables)

Apply a function to every item. Lazy: nothing runs until you consume it.

list(map(str, [1, 2]))               # ['1', '2']
n, m = map(int, input().split())     # parse a line of numbers
list(map(pow, [2,3], [3,2]))         # [8, 9]  two iterables
max(map(len, words))                 # no temp list built

Style. map(f, xs) beats a comprehension only when f already exists. map(lambda x: x*2, xs) is slower and uglier than [x*2 for x in xs].

filter(function, iterable)

Keep items where the test is true. Lazy.

list(filter(None, [0, 1, '', 2]))        # [1, 2]  drops falsy values
list(filter(str.isdigit, chars))         # only digits
list(filter(lambda x: x > 0, nums))      # prefer [x for x in nums if x > 0]
next(filter(pred, xs), None)             # find first match, lazily

Worth knowing. filter(None, xs) is the compact way to strip empties. Everything else reads better as a comprehension.

sorted(iterable, /, *, key=None, reverse=False)

A new sorted list. Timsort: O(n log n), stable, and O(n) on nearly sorted input.

sorted([3, 1])                             # [1, 3]
sorted(words, key=len)                     # by length
sorted(words, key=str.lower)               # case insensitive
sorted(people, key=lambda p: (-p.age, p.name))   # age desc, then name asc
sorted(counts.items(), key=lambda kv: kv[1], reverse=True)
sorted(d, key=d.get)                       # keys, ordered by value

Stable means. Equal items keep their original order. So you can sort twice: least important key first, most important key last.

reversed(seq, /)

A lazy iterator walking a sequence backwards.

list(reversed([1, 2]))           # [2, 1]
for i in reversed(range(n)):     # count down, no list built
    ...
''.join(reversed(s))             # same as s[::-1], but lazy
reversed(my_dict)                # keys, newest first. Python 3.8+

Trap. Generators and set have no order, so reversed rejects them. xs[::-1] copies; reversed(xs) does not.

all(iterable, /)

True when every item is truthy. Stops at the first false one.

all([1, 2, 0])                   # False
all([])                          # True   "no counter-example found"
all(x > 0 for x in nums)         # short-circuits on the first failure
all(isinstance(x, int) for x in xs)

Trap. Pass a generator, not a list comprehension. all([f(x) for x in xs]) evaluates every item before checking any of them.

any(iterable, /)

True when at least one item is truthy. Stops at the first true one.

any([0, 0, 3])                   # True
any([])                          # False
any(word in text for word in banned)     # exits early on a hit
if not any(errors): ship()       # "none of them" reads as `not any`

Inspect objects

Thirteen functions. Ask an object what it is and what it holds.

type(object) or type(name, bases, dict)

One argument reads a class. Three arguments create one.

type(1)                          # <class 'int'>
type(x).__name__                 # 'int'   just the name
type(x) is list                  # exact type, no subclasses
Point = type('Point', (), {'x': 0})   # a class made at runtime

Style. For a type check, use isinstance. Use type(x) is C only when a subclass must not pass.

isinstance(object, classinfo, /)

Is this value of that type, or a subclass of it?

isinstance(1, int)                     # True
isinstance(True, int)                  # True. bool subclasses int
isinstance(x, (int, float))            # either one
isinstance(x, int | str)               # 3.10+ syntax
isinstance(x, collections.abc.Iterable)   # "does it behave like one"

Trap. isinstance(True, int) is True. If you must reject booleans, test type(x) is int.

issubclass(class, classinfo, /)

Does one class inherit from another? Both arguments must be classes.

issubclass(bool, int)            # True
issubclass(int, int)             # True. A class is its own subclass
issubclass(int, object)          # True. Everything is
issubclass(1, int)               # TypeError. 1 is not a class

callable(object, /)

Can you put brackets after it? True for functions, classes and objects with __call__.

callable(len)                    # True
callable(int)                    # True. Classes are callable
callable(42)                     # False
callable(lambda: 1)              # True

Note. True is not a guarantee. Calling it can still raise TypeError on the arguments.

getattr(object, name, default)

Read an attribute whose name is a string.

getattr(obj, 'x')                # same as obj.x
getattr(obj, 'x', 0)             # 0 when missing
getattr(obj, field_name)         # the whole point: a dynamic name
handler = getattr(self, f'do_{cmd}', self.unknown)   # dispatch table

Use it for. Command dispatch and config-driven code. Avoid it when the name is a literal; obj.x is clearer and faster.

setattr(object, name, value, /)

Write an attribute whose name is a string.

setattr(obj, 'x', 5)             # same as obj.x = 5
for k, v in config.items():
    setattr(self, k, v)          # bulk-assign from a dict

Trap. Fails on classes using __slots__ if the name is not declared there.

delattr(object, name, /)

Remove an attribute whose name is a string.

delattr(obj, 'cache')            # same as del obj.cache
if hasattr(obj, 'tmp'):
    delattr(obj, 'tmp')          # guard first, or catch AttributeError

hasattr(object, name, /)

Does this attribute exist? Implemented as a getattr with the error caught.

hasattr([], 'append')            # True
hasattr(obj, 'read')             # duck typing: "is it file-like"

Trap. If the attribute is a property that raises, hasattr reports False. Prefer getattr(obj, name, sentinel) when that matters.

dir(object)

A sorted list of the names an object exposes. No argument gives the current scope.

dir()                                   # names defined right here
dir(str)                                # every string method
[m for m in dir(x) if not m.startswith('_')]   # the public surface
'append' in dir(obj)

Note. This is for humans exploring in a REPL. It can be customised by __dir__, so do not build logic on it.

vars(object)

The __dict__ of an object. No argument acts like locals().

vars(obj)                        # {'x': 5}
vars()                           # same as locals()
json.dumps(vars(obj))            # quick serialise of a simple object
vars(obj)['x'] = 9               # writes through. It is the real dict

Trap. Raises TypeError on objects with __slots__, and on ints and strings.

id(object, /)

A unique int for the object, for as long as it lives. In CPython, its memory address.

id(x) == id(y)                   # same object. Prefer `x is y`
a = [1]; b = a
id(a) == id(b)                   # True. Two names, one list

Trap. Ids are reused after an object is freed. Never store one as a long-lived key.

hash(object, /)

An int fingerprint. Equal objects must hash equal. Used by dicts and sets.

hash('a')                        # some int
hash(1) == hash(1.0)             # True. Equal values hash equal
hash([1])                        # TypeError: unhashable

Note. String hashes are randomised per process for security. Never persist one to disk. Use hashlib for a stable digest.

object()

The root of every class. Calling it gives a bare instance with no attributes.

MISSING = object()               # a unique sentinel value
def f(x=MISSING):
    if x is MISSING: ...         # distinguishes "not passed" from None
class C(object): ...             # Python 2 habit. Just write class C:

The real use. A sentinel. Nothing else in the program can ever equal it, so None stays free to be a valid value.

Write classes

Four functions. Three are used as decorators; the fourth reaches upward.

@classmethod

A method that receives the class, not the instance. Call it on the class or an instance.

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

    @classmethod
    def from_string(cls, text):        # an alternative constructor
        x, y = map(int, text.split(','))
        return cls(x, y)               # cls, so subclasses work too

Point.from_string('1,2')

Main use. Factory methods. Using cls(...) instead of Point(...) means a subclass gets its own type back.

@staticmethod

A plain function that lives inside a class. Gets neither self nor cls.

class Temp:
    @staticmethod
    def c_to_f(c):                     # no self needed
        return c * 9 / 5 + 32

Temp.c_to_f(100)                       # 212
Temp().c_to_f(100)                     # works on an instance too

When to use. A helper that belongs with the class for readability but touches no state. Since 3.10 these are callable as plain functions too.

@property or property(fget=None, fset=None, fdel=None, doc=None)

Make a method look like an attribute. Lets you add validation without changing callers.

class Circle:
    def __init__(self, r):
        self._r = r

    @property
    def area(self):                    # read as circle.area, no brackets
        return 3.14159 * self._r ** 2

    @property
    def r(self):
        return self._r

    @r.setter
    def r(self, value):                # validation on write
        if value < 0:
            raise ValueError('radius must be non-negative')
        self._r = value

Related. functools.cached_property computes once and stores the result on the instance.

super() or super(type, object_or_type)

A proxy to the next class in the method resolution order. Usually the parent.

class Base:
    def greet(self): return 'hi'

class Child(Base):
    def __init__(self, extra):
        super().__init__()             # run the parent's setup
        self.extra = extra

    def greet(self):
        return super().greet() + '!'   # extend, do not replace

Child.__mro__                          # the exact search order

Trap. "Next in the MRO" is not always the direct parent. With multiple inheritance it can be a sibling class. That is the feature, not a bug.

See the current scope

Two functions. Useful for debugging and templating, risky for logic.

globals()

The module-level namespace, as a real dict. Writing to it creates a global.

globals()['__name__']            # '__main__'
globals()['dynamic'] = 5         # really does create a global
fn = globals()['handler_' + name]    # look up a function by name

Better option. A plain dict of handlers is clearer than name lookups in globals(), and a linter can check it.

locals()

The local namespace as a dict. At module level it is the same as globals().

def f(a, b):
    c = a + b
    print(locals())              # {'a': 1, 'b': 2, 'c': 3}
'Hello {name}'.format(**locals())    # quick templating

Trap. Inside a function this is a snapshot copy. Assigning into it does not change the variable. Python 3.13 makes that explicit.

Run code from text

Four functions. Powerful, and the usual source of remote code execution bugs.

Read this before using any of the four. Never pass user input to eval, exec or compile. There is no safe sandbox; passing empty globals does not help. For data, use json.loads. For a literal Python value, use ast.literal_eval, which handles only strings, numbers, tuples, lists, dicts, sets and booleans.

eval(expression, globals=None, locals=None)

Run one expression and return its value. Statements are not allowed.

eval('2 + 3')                    # 5
eval('x * 2', {'x': 4})          # 8
eval('x = 1')                    # SyntaxError. That is a statement
ast.literal_eval('[1, 2]')       # the safe choice for data

exec(object, globals=None, locals=None)

Run a block of statements. Always returns None.

ns = {}
exec('def double(x): return x * 2', ns)
ns['double'](5)                  # 10

Legitimate use. Code generation inside libraries. dataclasses and namedtuple both build methods with exec.

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)

Turn source text into a code object you can run more than once.

code = compile('x + 1', '<expr>', 'eval')
eval(code, {'x': 1})             # 2. Reuse the code, skip re-parsing
tree = compile(src, 'f.py', 'exec', ast.PyCF_ONLY_AST)   # get the AST

Use it for. Static analysis via the AST, or a template engine that compiles once and runs many times.

__import__(name, globals=None, locals=None, fromlist=(), level=0)

The low-level hook behind the import statement.

__import__('math').pi                    # 3.14159...
__import__('os.path')                    # returns `os`, not `os.path`
__import__('os.path', fromlist=['path']) # returns os.path
importlib.import_module('os.path')       # do this instead

Do not use it. The return value rule is confusing. importlib.import_module does the same job correctly.

Files

One function, and it carries eight parameters.

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

Open a file and return a file object.

with open('f.txt', encoding='utf-8') as f:
    for line in f:                       # lazy. Never f.read() a big file
        process(line)

with open('out.txt', 'w', encoding='utf-8') as f:
    f.write('hi')

with open('img.png', 'rb') as f:         # binary: no encoding allowed
    data = f.read()

with open('log.txt', 'a', encoding='utf-8') as f:   # append, keeps content
    f.write('line\n')

Always use with. It closes the file even when an exception fires. And 'w' wipes an existing file the moment it opens, before you write a byte.

Debug and help

Two functions. Both are for you, not for production code.

help(request)

Print the docs for an object. No argument starts an interactive help session.

help(len)                        # the signature and docstring
help(str.split)                  # one method
help('modules')                  # every installed module
help(my_function)                # your own docstring shows here

Related. obj.__doc__ gets the raw docstring string, without the formatting.

breakpoint(*args, **kws)

Drop into the debugger at this line. Python 3.7+.

def f(x):
    breakpoint()                 # pdb opens here
    return x * 2

Two things worth knowing. Set PYTHONBREAKPOINT=0 to disable every breakpoint without editing code. Set PYTHONBREAKPOINT=ipdb.set_trace to swap in a nicer debugger.

Pairs people confuse

PairThe difference
str vs reprstr is for users, repr is for developers. repr shows the quotes.
sorted vs .sort()sorted returns a new list from any iterable. .sort() changes a list in place and returns None.
reversed vs [::-1]reversed is a lazy iterator. The slice builds a full copy.
type vs isinstancetype(x) is C rejects subclasses. isinstance accepts them. Use isinstance.
== vs is== compares values. is compares identity, the same thing id() reports.
int() vs round()int truncates toward zero. round goes to the nearest, ties to even.
iter vs nextiter makes the walker. next takes one step with it.
list vs tupleLists change and are unhashable. Tuples are fixed and can be dict keys.
set() vs {}{} is an empty dict. The empty set only has one spelling: set().
vars vs dirvars gives the instance data. dir gives every name, methods included.

Looks built-in, is not

These feel like built-ins but need an import, or left the language entirely.

NameWhere it lives now
reducefunctools.reduce. Moved out in Python 3 on purpose.
sqrt, floor, ceil, gcd, logmath. Only abs, pow, round, divmod are built in.
accumulate, chain, product, combinationsitertools.
Counter, defaultdict, deque, namedtuplecollections.
partial, lru_cache, cachefunctools.
reloadimportlib.reload.
raw_input, xrange, unicode, long, cmp, execfile, applyGone in Python 3. Use input, range, str, int.
Built-in names that are not functions. The builtins module also holds True, False, None, NotImplemented, Ellipsis (...), __debug__, and every exception class from Exception down. Run len(dir(__builtins__)) to see the whole set for your version.

Recap

← Guide 6: ML and Data Guide 1: The Python Toolkit →