Python
Local setup
Install pyenv and pyenv-virtualenv. Respectively for Python version management and virtualenvs management.
pyenv-virtualenv
usespython -m venv
(Python 3.3+) if it is available and thevirtualenv
command if not
On Mac
brew install pyenv-virtualenv
On Linux (Debian)
sudo apt-get update; sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
curl https://pyenv.run | bash
echo '''
# pyenv-virtualenv
# see https://github.com/pyenv/pyenv-virtualenv
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PATH:$PYENV_ROOT/bin
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
''' >> ~/.zshrc
source ~/.zshrc
Configure a Python 3 virtualenv
pyenv install --list | grep 3.9 | less # list possible python versions
pyenv install 3.9.6 # install a python version
pyenv virtualenv 3.9.6 python3 # create a new virtualenv
pyenv activate python3 # activate virtualenv
Other useful pyenv
commands:
pyenv deactivate # deactivate current virtualenv
pyenv versions # list installed python versions and available virtualenvs
pyenv which python # see path to python executable
pyenv version-name # see current virtualenv
pyenv uninstall python3 # remove virtualenv / python version
Generate a .python-version
file
pyenv version-name > .python-version
.python-version
is then used by pyenv-virtualenv
to automatically switch to correct virtualenv.
Generate a requirements.txt
file
pyenv virtualenv 3.9.6 [VENV_NAME] # create a new virtualenv
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'