Python
Local setup
Install pyenv to switch between Python versions.
Use python3 -m venv .venv
to create a local virtual environment.
In zsh, install zsh-autoswitch-virtualenv to autoswitch between local venvs.
To manage local project dependencies use poetry.
Use a specific Python 3 version
pyenv install 3.13 # install latest minor python version
pyenv local 3.13 # use newly installed python version
python3 -m venv .venv # create a virtualenv
# or mkvenv w/ zsh-autoswitch-virtualenv
Other useful pyenv
commands:
pyenv versions # list installed python versions
pyenv version-name # see current python version
pyenv which python # see path to python executable
pyenv uninstall 3.13.4 # remove python version, needs to be specific
Configure Poetry for dependency management
poetry config virtualenvs.create true --local
poetry init
To use poetry only for dependency management in pyproject.toml
add:
[tool.poetry]
package-mode = false
To add some deps:
poetry add mkdocs
poetry add -D black isort # dev deps
Generate a .python-version
file
Shouldn't be needed after running pyenv local ...
but in any other case:
echo $(pyenv version-name) > .python-version
.python-version
is then used by pyenv
to automatically switch to correct python version when navigating into the project's folder.
Generate a requirements.txt
file
Shouldn't be needed when using poetry but in any other case:
pyenv shell 3.13 # use specific python version
pip install [DEPENDENCY_1] [...] # install dependencies
pip freeze > requirements.txt # freeze requirements
Install dependencies from a requirements.txt file
pip install -r requirements.txt
Containerized Python development
Docs
Package registry
Snippets
#!/usr/bin/env python
Consult object help
help(set)
Parse arguments
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-i', '--requests-interval', type=float, default=5)
args = parser.parse_args()
print(args.verbose, args.requests_interval)
Reference: - https://docs.python.org/3/howto/argparse.html - https://docs.python.org/3/library/argparse.html
Performance counter
import time
start = time.perf_counter()
# ...
end = time.perf_counter()
print('timing: {time}'.format(time=(end - start)))
Reference count
import ctypes
def ref_count(address):
return ctypes.c_long.from_address(address).value
Interning
a = 10
b = int('1010', 2)
print(hex(id(a)))
print(hex(id(b)))
a is b # True, in [-5, 256]
a = 500
b = 500
a is b # False
String interning: don't do this unless optimization is needed
import sys
a = 'foo'
b = 'foo'
a is b # True, looks like an identifier so gets interned... but don't count on it
a = 'foo bar'
b = 'foo bar'
a is b # False
a = sys.intern('foo bar')
b = sys.intern('foo bar')
a is b # True
Peephole
def my_func():
a = 24 * 60
b = 'foo'
c = 'foo' * 2
d = ['foo', 'bar']
e = ('foo', 'bar')
f = {'foo', 'bar'}
print(my_func.__code__.co_consts)
# (None, 24, 60, 'foo', 2, 'bar', 1440, 'foofoo', ('foo', 'bar'))
Unpacking zen
Remove list duplicates
a = [1, 1, 2, 2, 3, 3]
*a, = {*a} # a = [1, 2, 3]
Overwrite dictionary values
a = {'foo': 'bar', 'baz': 'qux'}
b = {'foo': 'quux', 'quuz': 'courge'}
b = {**a, **b} # b = {'foo': 'quux', 'baz': 'qux', 'quuz': 'courge'}
Nested unpacking
a, *b, (c, d, e) = [1, 2, 3, 'XYZ']
# a = 1, b = [2, 3], c = 'X', d = 'Y', e = 'Z'