Python Notes
I’ve been learning a lot about Python recently. Here are some interesting things I’ve learned.
-
What’s the difference between
@classmethod
and@staticmethod
?@classmethod
gets it’s class (cls
by convention) as an implicit first argument. This means that it can modify class state if it wants. Static methods can’t do this. -
Python supports generic function in the style of R S3 methods through the
@singledispatch
decorator. -
If you need to iterate through something in reverse, use
reversed()
. - If you need to iterate through two things at once, use
zip()
. It will stop the iteration when the smaller of the two iterators stops.- You can pass a
zip
object to the dictionary constructor like this:dict(zip(a, b))
to make a dictionary with keys froma
and corresponding values fromb
.
- You can pass a
- The general term for a piece of data that signals the end of data (like a
\0
terminator in C) is a sentinel value. Notice that this is an example of old-style in-band signalling, rather than new-style out-of-band signalling, like an extra attribute (size) or exception (StopIteraton
).- In python, you can automatically convert an sentinel value to a
StopIteration
by passing it as the second argument toiter()
.
- In python, you can automatically convert an sentinel value to a
-
Partial function application is easy in Python. Just use
functools.partial()
. -
Every argument in a Python function can be either positional or keyword unless you explicitly indicate otherwise. To indicate the end of positional-only arguments, use the
/
argument. To indicate the beginning of keyword-only arguments, use the*
argument. -
Use
namedtuple
s to improve readibility as an alternative toenum.Enum
. -
If you find yourself adding/removing items from the beginning of a list with
del
,.pop(0)
or.insert(0, item)
, then you should be using adeque
. -
Use
with contextlib.suppress(e):
to temporarily suppress an exceptione
. -
To terminate a generator, never do
raise StopIteration
. This won’t work anymore. Instead, simply usereturn
. -
“Frozen” (as in
frozenset()
) doesn’t really have a special meaning in Python aside from immutable. -
Heaps offer a similar kind of partial ordering that you get in a tournament bracket.
- In Python, names have no type, but do have scope. By contrast, values have a type but no scope (i.e. they live in the heap).
- Note that Python is strongly typed, but typing applies only to values, not names.
-
deque
s are implemented as doubly linked lists, so they support popping from the ends in O(1), but indexing into the middle is O(n). - Use
@dataclasses.dataclass
if you want to define a struct-like class.- For simple structs that don’t need field names, just use tuples.
- Python technically supports both constructors and destructors with
.__init__()
and.__del__()
, but it’s more common to use context managers if you need to abstract away cleanup code.