« Python » : différence entre les versions
(→pip) |
|||
(8 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 070 : | Ligne 1 070 : | ||
<kode lang='ps'> | <kode lang='ps'> | ||
# create the virtual environment | # create the virtual environment in the folder my-env | ||
python -m venv --prompt ' | python -m venv my-env --prompt 'my-app' | ||
# default prompt is my-env | |||
# activate the virtual environment | # activate the virtual environment | ||
\my-env\Scripts\activate | \my-env\Scripts\activate | ||
# deactivate the current env | |||
deactivate | |||
# delete an env | |||
rm -r my-env | |||
# from the env, export the requirements | |||
pip freeze > requirements.txt | |||
# from the env, install the requirements | |||
pip install -r requirements.txt | |||
</kode> | </kode> | ||
Ligne 1 087 : | Ligne 1 098 : | ||
pip search "query" | pip search "query" | ||
# | # install a package | ||
pip install | pip install [package-name] | ||
# | # uninstall a package but not their dependencies | ||
pip uninstall | pip uninstall [package-name] | ||
# mettre à jour un paquet | # mettre à jour un paquet | ||
Ligne 1 125 : | Ligne 1 136 : | ||
Les paquets sont installés dans {{boxx|~/.local/lib/pythonX.X/site-packages}} ou {{boxx|/usr/lib/pythonX.X/site-packages}}<br> | Les paquets sont installés dans {{boxx|~/.local/lib/pythonX.X/site-packages}} ou {{boxx|/usr/lib/pythonX.X/site-packages}}<br> | ||
Les exécutables sont installés dans {{boxx|~/.local/bin}} ou {{boxx|/usr/bin}} ? }} | Les exécutables sont installés dans {{boxx|~/.local/bin}} ou {{boxx|/usr/bin}} ? }} | ||
== requirements.txt == | |||
<kode lang='bash'> | |||
# generate the list of required packages | |||
pip freeze > requirements.txt | |||
# install the required packages | |||
pip install -r requirements.txt | |||
</kode> | |||
== Erreurs == | == Erreurs == | ||
Ligne 1 132 : | Ligne 1 152 : | ||
# upgrade pip (ubuntu) | # upgrade pip (ubuntu) | ||
pip3 install --upgrade pip | pip3 install --upgrade pip | ||
</kode> | |||
= [https://pypi.org/project/pip-safe pip-safe] = | |||
Safe and easy pip package manager. Automatically install packages into python environments to not mess up with system packages. | |||
{{info | Add {{boxx|/usr/local/bin}} to your {{boxx|PATH}}}} | |||
<kode lang='bash'> | |||
# system-wide installation of a package | |||
sudo -H pip-safe --system install <package> | |||
# installs a package to /opt/pip-safe/<package> and symlinks its executable to /usr/local/bin | |||
# list installed packages | |||
pip-safe list | |||
# system-wide installation | |||
sudo mkdir -p /opt/pip-safe | |||
sudo chown [current-user]:[current-group] /opt/pip-safe | |||
python3 -m venv /opt/pip-safe/pip-safe | |||
/opt/pip-safe/pip-safe/bin/pip install pip-safe | |||
sudo chown root:root -R /opt/pip-safe | |||
sudo ln -s /opt/pip-safe/pip-safe/bin/pip-safe /usr/local/bin/pip-safe | |||
</kode> | </kode> |
Dernière version du 9 août 2024 à 10:09
Liens
Astuces
# Définit l'interpréteur à utiliser #!/usr/bin/env python import os scriptFolderPath = os.path.realpath("") """ Docstring Multi-lignes """ # Quitte le script exit("texte") # déclarer une variable nulle variable1 = None # Mettre le programme en attente pendant N secondes import time time.sleep(1) # Exécute un autre script execfile(r'chemin vers le fichier de script') # test si sudo a été utilisé pour lancer le script import os if os.getuid() == 0: # ok else: print("Lancer le script avec sudo.") |
Conventions de nommage
Package et modules (fichiers *.py) | lower_case_with_underscores |
Classes | CapWords (PascalCase, UpperCamelCase) |
Fonctions | lower_case_with_underscores |
Méthodes “privées” | _start_with_underscores |
Console I/O
# Affiche le texte et attend une saisie nombre = input('Entrez un nombre > ') print(nombre) # Effacer la console os.system('cls') # Afficher du texte dans la console. %r est remplacé par la variable correspondante. print('Texte ', variable1, ' suite') print('Texte ' + str(variable1) + ' suite') print('Texte {} suite'.format(variable1)) # Afficher du texte sans retour à la ligne mais avec un espace à la fin print("Texte", end="") # Afficher du texte sans retour à la ligne et sans espace à la fin import sys sys.stdout.write("Texte") |
Arguments passés au script
optparse est obsolète, utiliser argparse |
from argparse import ArgumentParser parser = ArgumentParser(prog='myprogram', description='Courte description du programme') # prog permet de redéfinir le nom du programme (défaut: sys.argv[0]) # argument positionnel parser.add_argument('action') # argument optionnel avec une valeur parser.add_argument('-f', '--file') # argument optionnel associé à une constante booléenne parser.add_argument("-r", "--recursive", action="store_true", help="description de l'argument. [default: %(default)s]")) # -h est déjà inclus par défaut parser.add_argument('-v', '--version', action='version', version='%(prog)s v1.0 (2017-07-03)') # Process arguments args = parser.parse_args() file = args.file # -f file.txt → file.txt recursive = args.recursive # -r → True |
usage: myprogram [-h] [-f FILE] [-r] [-v] action Courte description du programme positional arguments: action optional arguments: -h, --help show this help message and exit -f FILE, --file FILE -r, --recursive description de l'argument. [default: False] -v, --version show program's version number and exit
sys.argv
import sys # nombre d'arguments (+1 pour le nom du script) if len(sys.argv) != 2: exit('Utilisation: {} argument1'.format(os.path.basename(sys.argv[0]))) sys.argv[0] # nom du script sys.argv[1] # premier argument |
String
Python 3 utilise la table unicode pour les string. |
# longueur de la chaîne longueur = len(string1) # 2 # r : raw string literals. \ n'est pas interprété print(r'test \n test') # test \n test # rechercher un sous-élément, retourne l'index du sous-élément sinon -1 string2.find('deux') # remplacer les . par des ! string2 = string1.replace(".", "!") |
Concatenation and interpolation
Fichier:Py.svg | # concatenation string1 = 'un' string2 = string1 + ' - deux' # l'opérateur += est déjà optimisé, un StringBuilder est inutile string2 += ';' # interpolation string2 = f'{string1} - deux' |
Comparison
Fichier:Py.svg | string3 = '' # test si une chaîne est vide: empty strings are "falsy" if not string3: # chaine1 est vide # comparaison de string en ignorant la casse if string1.lower() == string2.lower(): if string1.endswith('xxx'): |
Split
Fichier:Py.svg | # split et rsplit url = 'http://www.domain.fr/fichier.txt' url.split('/') # ['http:', '', 'www.domain.fr', 'fichier.txt'] url.split('/')[-1] # fichier.txt # maxsplit = 1. Nb de groupes: maxsplit + 1 (le reste) url.split('/', 1) # ['http:', '/www.domain.fr/fichier.txt'] url.rsplit('/', 1) # ['http://www.domain.fr', 'fichier.txt'] url.rsplit('/', 1)[1] # fichier.txt |
Nombres
entier = 1 décimal = 2.0 somme = entier + décimal # 3.0 int(décimal) # 2 float(entier) # 1.0 |
Booléen
vrai = True faux = False int(vrai) # 1 int(faux) # 0 |
datetime
import datetime from dateutil.parser import parse ma_variable = f'text-{datetime.date.today()}-text}' # text-yyyy-mm-dd-text ma_variable = "text-%s-text" % ( datetime.date.today() ) parse('03/08/2017') # 2017-03-08 00:00:00 parse('03/08/2017', dayfirst=True) # 2017-08-03 00:00:00 |
Python: Get Today’s Current Date and Time
If else
if a == b and a == c or b != c: commande1 commande2 elif not b == c: commande3 else: commande4 if myInteger: print('myInteger is defined and not equal to 0') if myString: print('myString is defined and not an empty string') # sur un ligne commande1 if a == b else commande2 |
Liste / Tableau / Array
myList = [] # une liste peut contenir des éléments hétérogènes: int, string myList = ['zéro', 1, 'deux', 'trois'] myList[1] # 1 myList[1] = 'un' myList[:2] # éléments 0 ≤ index < 2: zéro 1 myList[2:] # éléments 2 ≤ index : deux trois myList[1:3] # éléments 1 ≤ index < 3: 1 deux myList[-1] # dernier élément: trois myList[-2:] # 2 derniers éléments: deux trois myList[-3:-1] # 3 derniers éléments moins le dernier: 1 deux myList[0:4:2] # 1 élément sur 2: zéro deux myList.append(4) # ['zéro', 'un', 'deux', 'trois', 4] del myList[1] # supprime l'élément à l'index 1 myList.pop(1) # supprime et retourne l'élément à l'index 1 myList.remove('deux') # supprime la première valeur correspondante # nombre d'éléments dans myList len(myList) # 5 # test si myList contient 4 if 4 in myList: # trie de la liste myList.sort() myList.sort(reverse=True) # trier des caractère utf-8 import locale # forcer la locale locale.setlocale(locale.LC_ALL, '') #print(locale.getlocale()) myList.sort(key=locale.strxfrm) # concaténation des éléments d'une liste ''.join(myList) # générer une liste d'entier range(6) # [0, 1, 2, 3, 4, 5] range(5, 11) # [5, 6, 7, 8, 9, 10] range(0, 11, 2) # [0, 2, 4, 6, 8, 10] |
List Comprehensions: filtre et projection
# filtre des nombres pair à partir de [0, 1, 2, 3, 4, 5] [x for x in range(6) if x%2 == 0] # [0, 2, 4] # équivalent avec filter filter(lambda x: x%2 == 0, range(6)) # projection de [0, 1, 2, 3, 4, 5] où chaque élément est multiplié par 2 (x*2) [x*2 for x in range(6)] # [0, 2, 4, 6, 8, 10] # équivalent avec map map(lambda x: x*2, range(6)) |
yield
Avec yield, le code n'est pas exécuté à l'appel de la méthode mais à la demande.
def my_method(max_value): for i in range(max_value) yield i*2 my_generator = my_method(10) # le code de my_method n'est pas exécuté ici for i in my_generator: # mais ici, à la demande |
Affiche multi-colonnes
for a,b,c in zip(myList[::3], myList[1::3], myList[2::3]): print('{:<30}{:<30}{:<}'.format(a,b,c)) |
Tuple
# équivalent d'une liste mais # - on ne peut ni ajouter ni supprimer des éléments # - les valeurs des éléments ne peuvent être modifiées myTuple = ('un', 'deux', 'trois') |
Dictionnaires
dico = {} dico = {'key a': 'value a', 'key b': 'value b'} dico['key a'] # value a dico['key c'] # KeyError: 'key c' dico.get('key c') # None dico.get('key c', 'Unknown') # Unknown dico['key c'] = 'value c' del dico['key b'] for k, v in dico.items(): print(k, v) |
Set
Collection d'éléments unique indexés. Utilisé pour les opérations telles que intersection ou difference
Fichier:Py.svg | my_set = set(my_list) diff = my_set.difference(my_other_set) |
For
animaux = ['chat', 'serpent'] for animal in animaux: print(animal) break # sort de la boucle for continue # passe à l'itération suivante else: # on entre dans else une fois toutes les itérations parcourues # donc pas si break a été utilisé print("fin sans break") # for avec une condition if list = ['aa', 'ab', 'ac'] [print(x[1]) for x in list if x.endswith('b')] for y in (x[1] for x in list if x.endswith('b')): print(y) # for avec une condition lambda expression z = lambda x: print(x[1]) if x.endswith('b') else None [z(x) for x in list] for folder in filter(lambda folder: os.path.isdir(os.path.join(cwd, folder)), os.listdir()): |
While
i = 0 while i < 10: i += 1 list = [1, 2, 3] while 3 in list: |
Exceptions
try: raise Exception('EEE') except ImportError: # capture les exceptions de type ImportError pass except (RuntimeError, TypeError, NameError): # capture les exceptions de type RuntimeError, TypeError et NameError pass except Exception as e: # permet d’accéder à l'instance de l'exception print(e) # affiche le message d'erreur except: # capture toutes les exceptions restantes raise # relance l'exception précédemment capturée else: # contient le code qui sera exécuté si aucune exception n'est lancée dans le bloc try pass |
Expressions rationnelles
Méthodes | Description |
---|---|
match() | Determine if the RE matches at the beginning of the string. |
search() | Scan through a string, looking for any location where this RE matches. |
findall() | Find all substrings where the RE matches, and returns them as a list. |
finditer() | Find all substrings where the RE matches, and returns them as an iterator. |
split() | Split the string into a list, splitting it wherever the RE matches |
sub() | Find all substrings where the RE matches, and replace them with a different string |
subn() | Does the same thing as sub(), but returns the new string and the number of replacements |
Compilation Flags | |
---|---|
DOTALL, S | Make . match any character, including newlines |
IGNORECASE, I | Do case-insensitive matches |
MULTILINE, M | Multi-line matching, affecting ^ and $ ^ devient le début de ligne au lieu du début du texte $ devient la fin de ligne au lieu de la fin du texte |
search
import re # compiler l'expression rationnelle si elle est utilisée plusieurs fois regex = re.compile('expression rationnelle') match = re.search(regex, 'texte') if match: print('Une correspondance a été trouvée: ', match.group(0)) else: print "l'expression %r n'a pas été trouvée" % (regex) # Utilisation des groupes match = re.search(r"(\w+) (\w+)", "John Smith") print match.group(0) # 'John Smith', retourne la correspondance complète print match.group(1) # 'John', retourne la correspondance avec le groupe 1 print match.group(2) # 'Smith', retourne la correspondance avec le groupe 2 |
finditer
for match in re.finditer('(?P<groupe1>\d+) (?P<groupe2>\d+)', texte): # regroupe les résultats dans un dictionnaire au lieu d'un tableau match.groupdict() # match.group('groupe1') |
Substitution
import re nouveauTexte = re.sub('expression rationnelle', 'substitution', 'texte') # Avec le drapeau MULTILINE nouveauTexte = re.sub(re.compile('expression rationnelle', re.MULTILINE), 'substitution', 'texte') # Normalement avec Python 2.7 on devrait pouvoir écrire nouveauTexte = re.sub('expression rationnelle', 'substitution', 'texte', flags=re.MULTILINE) # mais ça ne marche pas avec IronPython 2.7 # Exemple avec les groupes re.sub('(texte) (intéressant)', '\g<2> \g<1>', 'un texte intéressant') # un intéressant texte |
Fonctions
def my_function(arg1, arg2): ''' Description de la fonction. :param arg1: Description de l'argument. :param arg2: Description de l'argument. :return: Description du contenu retourné par la fonction. ''' return f'{arg1} - {arg2}' # type hinting, permet d'informer sur les types attendus des arguments des fonctions ainsi que du type de retour def my_function(arg1: str, arg2: str) -> str: return f'{arg1} - {arg2}' # appel de la méthode my_function('start', 'end') # start - end # argument optionnel def my_function(arg1, arg2 = 'end'): return f'{arg1} - {arg2}' # appel de la méthode my_function('start') # start - end my_function('start', 'next') # start - next # liste d'arguments. args est un tuple. def my_function(*args): return ' - '.join(args) # appel de la méthode my_function('start', 'next', 'end') # start - next - end # dictionnaire d'arguments (keywords arguments). def my_function(**kwargs): for k, v in kwargs.items(): yield f'{k} - {v}' # appel de la méthode '\n'.join(my_function(un = 1, deux = 2)) # un - 1 # deux - 2 |
Modules et Packages
- Les modules sont des fichiers *.py
- Les packages sont des dossiers qui représentent les namespaces. Ils contiennent un fichiers __init__.py
__init__.py |
# par défaut tous les modules d'un package sont accessible # pour rendre des modules inaccessibles, il faut redéfinir __all__ en listant seulement les modules accessibles __all__ = ["module1"] |
POO
Classe
my_class.py |
class MyClass(object): # hérite de object """ documentation pour la classe multi-lignes """ # accessible depuis la classe et ses instances. # tant que l'instance ne modifie pas la valeur elle est égale à celle de la classe # l'instance peut modifier la valeur sans que la valeur de la classe soit modifiée classAttribute = 0 # Initialiseur def __init__(self, someValue): """ documentation du constructeur """ self.MyAttribute = someValue # méthode d'instance, self représente l'instance de l'objet courant def myMethod(self, Arg1, Arg2 = 0): self.MyAttribute = Arg1 return Arg2 # méthode de classe, cls représente la classe de l'objet courant @classmethod def myClassMethod(cls): cls.classAttribute += 1 # méthode statique @staticmethod def myStaticMethod(): MaClass.classAttribute += 1 |
main.py |
from my_class import MyClass if __name__ == '__main__': myObject = MyClass("Arg1") # Afficher tous les attributs d'un objet print(dir(myObject)) print(myObject.MyAttribute) # Arg1 print(myObject.classAttribute) # 0 print(MyClass.classAttribute) # 0 retour = myObject.myMethod("Arg2", 10) print(myObject.MyAttribute) # Arg2 print(retour) # 10 MyClass.myClassMethod() print(MyClass.classAttribute) # 1 MyClass.myStaticMethod() print(MyClass.classAttribute) # 2 |
Tous les arguments sont passés par référence |
Héritage
class A(): def __init__(self): self.Attribute1 = 10 def Who(self): print("A") class B(): def Who(self): print("B") # il est possible d'hériter de plusieurs classes, l'héritage se fait dans l'ordre d'écriture A puis B class C(A, B): # si aucun constructeur n'est définit, c'est celui de la première classe parente qui est appelé (A) def __init__(self): # appel explicite du constructeur de la classe parente A A.__init__(self) # code équivalent super(B).__init__(type(self)) # surcharge de la méthode Who def Who(self): # A.Who(self) print("B") |
Variables globales
globvar = 0 def modifyGlobvar1(): # globvar est ici zûne variable locale à la fonction modifyGlobvar1 globvar = 1 def modifyGlobvar2(): # pour pouvoir modifier la variable globale, il faut utiliser le mot-clé global global globvar globvar = 2 def printGlobvar(): # comme aucune variable globvar n'existe au niveau de la fonction, on va chercher un niveau plus haut pour l'accès en lecture print(globvar) printGlobvar() # 0 modifyGlobvar1() printGlobvar() # 0 modifyGlobvar2() printGlobvar() # 2 |
Fichiers
Création - suppression - copie
import os # déplacer un fichier, le fichier de destination est écrasé s'il existe os.rename('/dossier1/fichier1', '/dossier2/fichier2') # supprimer un fichier os.remove(r'chemin vers le fichier') |
Lecture - écriture
# mode d'ouverture: # r → read # w → write, écrase le contenu du fichier # a → append, ajoute à la fin du fichier, s'il n'existe pas le fichier est créé with open('chemin vers le fichier', 'r') as fichier: # lit tout le contenu du fichier et renvoie une chaîne de caractères unique contenuFichier = fichier.read() # lecture ligne par ligne for line in fichier.read_lines(): fichier.write('texte') |
Télécharger un fichier
import requests import shutil url = 'http://www.doamin.fr/file.zip' local_filename = url.split('/')[-1] # file.zip r = requests.get(url, stream=True) with open(local_filename, 'wb') as f: shutil.copyfileobj(r.raw, f) |
Répertoires
Création - suppression - copie
import os, shutil # création d'un répertoire os.mkdir(r'chemin vers un dossier') # supprimer un dossier et son contenu récursivement shutil.rmtree(r'chemin vers le dossier') # copier un dossier et son contenu récursivement shutil.copytree('source', 'destination') # ignore permet de filtrer les fichiers et dossiers à ne pas copier shutil.copytree('source', 'destination', ignore=shutil.ignore_patterns('*.log', '*.py')) |
Parcourt
import os, glob # renvoie la liste des noms des dossiers du répertoire passé en paramètre folder_names = [x.name for x in os.scandir('/media/data') if x.is_dir()] # renvoie la liste des chemins des fichiers du répertoire passé en paramètre file_names = [x.path for x in os.scandir('/media/data') if x.is_file()] # renvoie la liste des noms des fichiers et dossiers du répertoire passé en paramètre for name in os.listdir('/path/folder'): # no parameter in listdir means current directory for filename in [x for x in os.listdir() if re.search('*.mp4', x)]: # utilisation des caractères * et ? dans le chemin for path in glob.glob(r'/chemin/vers/un/dossier/*.ext'): # parcourt récursif du dossier passé en paramètre # root contient le chemin complet vers le dossier parcourut # dirs contient la liste des sous-répertoires du dossier parcourut # files contient la liste des fichiers du dossier parcourut # le paramètre topdown=False permet de parcourir l'arbre de bas en haut for root, dirs, files in os.walk(r'chemin vers un dossier'): |
Path
import os from os import path # test si le chemin correspond à un fichier ou à un dossier if path.exists(r'chemin vers un dossier'): # test si le chemin correspond à un fichier if path.isfile(r'chemin vers un fichier'): # test si le chemin correspond à un dossier if path.isdir(r'chemin vers un dossier'): # obtient le chemin vers le répertoire contenant le fichier spécifié directoryPath = path.dirname(r'chemin vers le fichier') # obtient uniquement le nom du fichier spécifié fileName = path.basename(r'chemin vers le fichier') # get the filename without the extension and the extension path.splitext(r'/path/file.ext') # [0]=file [1]=.ext # donne le chemin courant os.getcwd() # change le chemin courant os.chdir('/path') # concatène intelligemment deux chemins path.join('/path', 'file-name.ext') # renvoit le chemin absolu courant concaténé au chemin spécifié path.realpath('/path') # renvoit le chemin vers le dossier personnel de l'utilisateur courant (C:\Users\Nicolas) path.expanduser('~') # teste si le chemin est un point de montage path.ismount('/path') # chemin vers le script courant tel qu'il a été passé dans la ligne de commande __file__ sys.argv[0] |
logging
Logger | objet qui permet d'appeler les méthodes de log |
Handler | envoie le message de log vers une destination: console, fichier |
Filter | filtre les messages de log |
Formatter | décrit la mise en forme du message de log |
import logging logging.basicConfig( # changement du format d'affichage format = '%(asctime)s %(levelname)s - %(filename)s,%(funcName)s,%(lineno)d: %(message)s', # changement du format de date datefmt = '%d/%m/%Y %H:%M:%S' # changement du niveau de log (défaut: WARNING) level = logging.DEBUG, # log dans un fichier (défaut: console) filename = 'app.log') # 06/08/2017 17:46:30 WARNING - main.py,<module>,15: LOG !!! # logging représente le logger root logging.warning('LOG !!!') # WARNING:root:LOG !!! try: # ... except Exception, e: logging.error('Failed', exc_info=True) # affiche la Traceback |
Handlers
Permet de loguer dans plusieurs destinations en même temps.
import logging.handlers logger = logging.getLogger() # logger root logger.setLevel(logging.NOTSET) # par défaut à WARNING filehandler = logging.handlers.RotatingFileHandler('main.log', maxBytes=1024, backupCount=1) filehandler.setLevel(logging.ERROR) filehandler.setFormatter( logging.Formatter( '%(asctime)s %(levelname)s - %(name)s,%(filename)s,%(funcName)s,%(lineno)d: %(message)s', datefmt = '%d/%m/%Y %H:%M:%S')) logger.addHandler(filehandler) consolehandler = logging.StreamHandler() consolehandler.setLevel(logging.INFO) consolehandler.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) logger.addHandler(consolehandler) logger.error('Test !!!') |
Loggers
Sélectionne le logger à utiliser en fonction du besoin.
# __name__ correspondant à Package.Module, permet de récupérer le logger du module courant logger = logging.getLogger(__name__) # si aucun logger ne correspond à Package.Module, on cherche son parent Package, sinon root |
Fichier de configuration
import yaml # installer python-yaml with open('logging_configuration.yaml', 'rt') as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) |
logging_configuration.yaml |
version: 1 # obligatoire disable_existing_loggers: False # True par défaut, désactive les loggers définis avant l'appel dictConfig formatters: file_formatter: format: "%(asctime)s %(levelname)s - %(name)s,%(filename)s,%(funcName)s,%(lineno)d: %(message)s" console_formatter: format: "%(levelname)s - %(message)s" handlers: console: class: logging.StreamHandler level: INFO formatter: console_formatter stream: ext://sys.stdout file_handler: class: logging.handlers.RotatingFileHandler level: ERROR formatter: file_formatter filename: info.log maxBytes: 1024 backupCount: 1 encoding: utf8 root: level: NOTSET # par défaut à WARNING, ignore donc DEBUG et INFO handlers: [console, file_handler] |
coloredlogs
pip install coloredlogs # Installe coloredlogs et sa dépendance humanfriendly |
logging_configuration.yaml |
formatters: colored_console_formatter: (): coloredlogs.ColoredFormatter level_styles: # black, blue, cyan, green, magenta, red, white, yellow debug: color: green verbose: color: magenta info: color: cyan warning: color: yellow error: color: red critical: color: red bold: True field_styles: hostname: color: magenta programname: color: cyan name: color: blue levelname: color: white bold: True asctime: color: green format: "%(levelname)s - %(message)s" |
python-sh
Permet d'appeler les commandes bash sous forme de méthodes python.
from sh import pgrep print(pgrep('firefox')) |
# installation pacman -S python-sh |
Appel système
import subprocess # appel d'une commande bash subprocess.run(["ls", "-a", "-l"]) # permet de gérer les espaces dans les arguments subprocess.run("ls -a -l", shell=True) # capture output completedProcess = subprocess.run(["ls", "-a", "-l"], capture_output=True) print(completedProcess.stdout.decode("utf-8")) # decode: bytes → string # redirige stdout subprocess.run(["ls", "-l"], stdout=subprocess.DEVNULL) # appel d'un script bash, inutil d'ajouter shell=True si le script contient #!/usr/bin/bash completedProcess = subprocess.run("./my-script.sh") print(completedProcess.returncode) # 0 # lance une subprocess.CalledProcessError si le script retourne une valeur ≠ de 0 try: subprocess.run("./my-script.sh", check=True) except subprocess.CalledProcessError as e: print(e) # Command './my-script.sh' returned non-zero exit status 127. |
Pipe
import subprocess from subprocess import PIPE # ls ~ | tail -n 3 | xargs output = subprocess.check_output("ls ~ | tail -n 3 | xargs", stderr=subprocess.STDOUT, shell=True) # check_output is equivalent to run(..., check=True, stdout=PIPE).stdout ls = subprocess.Popen(['ls', '~'], stdout=PIPE, stderr=PIPE) tail = subprocess.Popen(['tail', '-n', '3'], stdin=ls.stdout, stdout=PIPE, stderr=PIPE) xargs = subprocess.Popen(['xargs'], stdin=tail.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = xargs.stdout.read().strip().decode("utf-8") xargs = subprocess.run(['xargs'], stdin=tail.stdout, stdout=PIPE, stderr=PIPE) output = xargs.stdout |
check_call
Si le code de retour n'est pas 0, lève une CalledProcessError.
import subprocess from subprocess import CalledProcessError, DEVNULL try: subprocess.check_call(['ping', '-c', '1', 'remote'], stdout=DEVNULL) except CalledProcessError as e: print(f'{e.returncode} - {e.cmd} - {e.output} - {e.stdout} - {e.stderr}') exit(f'{e.cmd[3].upper()} is not reachable.') |
JSON
Fichier:Py.svg | import json # load json content from a file with open('/path/file.json') as my_file: my_dict = json.load(my_file) # load json content from a string my_dict = json.loads(json_content) # access content my_dict['my_key'] |
Process
Fichier:Py.svg | while ('firefox' in (p.name() for p in psutil.process_iter())): input('Close Firefox to continue.') |
ASQ - LINQ
Préférer l'utilisation native de List Comprehensions |
Équivalent de LINQ pour Python.
pip install asq |
from asq.initiators import query words = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"] # premier mot commençant par f: four query(words).first(lambda w: w.startswith('f')) |
SSH avec Fabric
from fabric import Connection result = Connection('remote-hostname').run('ls', hide=True) msg = "Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}" print(msg.format(result)) # ferme la connection à la sortie du with with Connection('remote-hostname', user='usr', password='pwd') as c: c.get('/path/file.ext', local='/path/folder') |
Archives
zip
import zipfile # extraire tous le contenu de l'archive dans le dossier courant with zipfile.ZipFile(path) as z: z.extractall() |
gzip
import gzip with gzip.open('/chemin/fichier.gz', 'rb') as f: content_in_bytes = f.read() content = content_in_bytes.decode("utf-8") |
CSV
with open(path, newline='') as csvfile: reader = csv.reader(csvfile, delimiter=';') for row in reader: print(row) # utilise la première ligne comme clés pour le dictionnaire reader = csv.DictReader(csvfile, delimiter=';') for row in reader: print(row['nom_colonne_1'], row['nom_colonne_5']) |
Virtual Environments
Self-contained directory tree that contains a Python installation for a particular version of Python, plus a number of additional packages.
# create the virtual environment python3 -m venv --prompt '|> my-app <| ' my-env # activate the virtual environment source my-env/bin/activate |
# create the virtual environment in the folder my-env python -m venv my-env --prompt 'my-app' # default prompt is my-env # activate the virtual environment \my-env\Scripts\activate # deactivate the current env deactivate # delete an env rm -r my-env # from the env, export the requirements pip freeze > requirements.txt # from the env, install the requirements pip install -r requirements.txt |
pip
Gestionnaire de paquets pour python.
Il est déconseiller d'installer des paquets avec sudo. |
Use python3 -m pip instead of pip |
# chercher un paquet pip search "query" # install a package pip install [package-name] # uninstall a package but not their dependencies pip uninstall [package-name] # mettre à jour un paquet pip install -U paquet # lister les paquets à mettre à jour pip list --outdated # lister tous les paquets installés avec pacman et pip pip list --format=columns # lister les paquets installés avec pip seulement find /usr/lib/python3.9/site-packages -maxdepth 2 -name __init__.py | xargs pacman -Qo | grep 'No package' find ~/.local/lib/python3.9/site-packages -maxdepth 2 -name __init__.py | xargs pacman -Qo | grep 'No package' # Ubuntu find /usr/local/lib/python3.6/dist-packages -maxdepth 2 -name __init__.py | xargs realpath | xargs dpkg -S 2>&1 | grep 'no path found' # afficher des infos sur un paquet pip show [package_name] # lister les paquets et leurs dépendances pipdeptree # afficher pourquoi un paquet est installé pipdeptree --reverse --packages [package_name] |
Ubuntu: Les paquets sont téléchargés dans $HOME/.cache/pip |
ArchLinux: Les paquets à installer se nomment python-pip ou python2-pip |
requirements.txt
# generate the list of required packages pip freeze > requirements.txt # install the required packages pip install -r requirements.txt |
Erreurs
TypeError: '>' not supported between instances of 'Version' and 'Version'
Désinstaller la version pip du système et installer celle fournie par pypa.
# upgrade pip (ubuntu) pip3 install --upgrade pip |
pip-safe
Safe and easy pip package manager. Automatically install packages into python environments to not mess up with system packages.
Add /usr/local/bin to your PATH |
# system-wide installation of a package sudo -H pip-safe --system install <package> # installs a package to /opt/pip-safe/<package> and symlinks its executable to /usr/local/bin # list installed packages pip-safe list # system-wide installation sudo mkdir -p /opt/pip-safe sudo chown [current-user]:[current-group] /opt/pip-safe python3 -m venv /opt/pip-safe/pip-safe /opt/pip-safe/pip-safe/bin/pip install pip-safe sudo chown root:root -R /opt/pip-safe sudo ln -s /opt/pip-safe/pip-safe/bin/pip-safe /usr/local/bin/pip-safe |