Skip to content

Python

pyenv

Install pyenv

1
2
3
$ sudo apt-get install -y make build-essential git libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev

$ curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash

Also, add the following to your ~/.bashrc or ~/.zshrc:

1
2
3
4
5
# PyEnv
export PATH="${HOME}/.pyenv/bin:${PATH}"
eval "$(${HOME}/.pyenv/bin/pyenv init --path)"
eval "$(${HOME}/.pyenv/bin/pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Cheatsheet

Main usage is:

  • Install a new Python version
  • Create a new virtualenv using this version
  • Make your project use this virtualenv
  • Install dependencies / run your project inside this virtualenv
1
2
3
4
5
6
7
$ pyenv install 3.12.1
$ pyenv rehash
$ pyenv virtualenv 3.12.1 my-project
$ cd ~/workspace/my-project
$ pyenv local my-project
$ python --version
# Python 3.12.1

pyenv install

List available remote Python versions you can install:

$ pyenv install -l

Install Python 3.9.12:

$ pyenv install 3.9.12
$ pyenv rehash

pyenv versions

List locally installed versions:

$ pyenv versions

pyenv local

Set a local application-specific pyenv virtualenv in the current directory:

1
2
3
$ pwd
# ~/workspace/my-project
$ pyenv local my-pyenv-virtualenv-name

Set a local application-specific pyenv virtualenv in the current directory:

$ pyenv local 2.7.6

Unset the local version:

1
2
3
$ pyenv local --unset
# or
$ rm .python-version

pyenv virtualenv

List locally created virtualenvs:

$ pyenv virtualenvs

Create a new virtualenv:

1
2
3
4
# From system's Python version with name `my-project`:
$ pyenv virtualenv my-project
# From a given Python version:
$ pyenv virtualenv 3.9.12 my-other-project

Delete an existing virtualenv:

$ pyenv uninstall my-project

Upgrade pyenv

$ cd $(pyenv root)
$ git pull

List

Sort list of dicts based on a dict's key

1
2
3
4
my_unsorted_list = [ {"name": "Julien", "age": 12}, {"name": "Xavier", "age": 20}, {"name": "Alex", "age": 43}]
sorted(my_unsorted_list, key=lambda d: d["name"])
# Output
# [{'name': 'Alex', 'age': 43}, {'name': 'Julien', 'age': 12}, {'name': 'Xavier', 'age': 20}]

Select random item in a list

1
2
3
4
5
import random

my_list = [1, 2, 3, 4]
random.choice(my_list)
# 2

Archives

Create a .tar.gz archive. Suppose you have this source folder structure:

1
2
3
4
5
.
└── source-dir
    β”œβ”€β”€ file1
    β”œβ”€β”€ file2
    └── file3

Then:

1
2
3
4
import tarfile

with tarfile.open(f"source-dir.tgz", "w:gz") as tar:
    tar.add("source-dir")

Will create a source-dir.tgz archive containing the exact same structure (keeping the source-dir):

To only add files to the archives (without keeping source-dir):

import os
import tarfile

with tarfile.open(f"source-dir.tgz", "w:gz") as tar:
    for filename in os.listdir("source-dir"):
        tar.add(
            os.path.join("source-dir", filename), # source file path
            arcname=filename,                     # name of the file in the archive
            recursive=False,                      # should we keep the source structure, aka keep "source-dir/filename" ?
        )

Will create a source-dir.tgz archive with this structure:

1
2
3
4
.
β”œβ”€β”€ file1
β”œβ”€β”€ file2
└── file3

Other compression algorithms are supported (bz2, lzma etc). Official doc