2.Concepts
Généralités
- Overview:
- Language interprété
- Pas de mot clé pour déclarer une variable, peut intervenir n'importe où
- Promotion float, pas int
- any non-zero integer value is true
pass
: statement qui ne fait rien, utile pour squelette d'une fonction ou classe ou pour meubler une boucle en attendant l'implementation (vu qu'il n'y a pas d'acolades….)
- Virtual Environments:
- Est un espace pour garder différents projets Python séparés et propres
- Chaque espace (= virtual env) contient une copie propre de Python et des bibliothèques
- Comparable au 'node_modules' mais inclus également une copie du runtime Python pour cet env
- a self-contained directory tree that contains:
- a Python installation for a particular version of Python
- a number of additional packages
- Named "venv"
- Créer un venv:
py -m venv NOMENV
- Créé un répertoire NOMENV
- Met à jour le fichier settings.json de VSCode, variable
python.pythonPath
- Créer un venv pour une version spécifique de python (après l'avoir installé):
py -<major>.<minor> -m venv NOMENV
- Gestion du venv:
- Activer:
NOMENV\Scripts\activate.bat
- Desactiver:
NOMENV\Scripts\deactivate.bat
- Gestion des packages PIP:
- Relatif au venv courant
- Installation pip:
- Installé avec Python sous Windows
- Autrement:
py -m pip install --upgrade pip
pip install NOM[==X.Y.Z]
pip uninstall NOM
pip show NOM
pip list
Control Flow
- Operators:
//
= floor division = retourne un entier et non un float
**
= power
in
= test si une valeur appartient à la séquence => if 3 in [1, 2, 3]
- All comparison operators have the same priority, which is lower than that of all numerical operators.
if
:
if <condition>:
Action
elif <condition>:
Action
else:
Action
for
:
- itère sur n'importe quel type de séquence
- Pour réccupérer les k,v des dictionnaires :
for k, v in dict.items()
…
- Pour réccupérer l'index et la valeur d'une collection non-dictionnaire :
for i, v in enumerate(coll)
…
zip()
permet de contenir des collections afin de les parcourir en parallèle
Break
: interrompt la boucle sans executer le else
Continue
: passe à l'itération suivante
for <nom var, type retourné par la fonction iter de la sequence> in <sequence iterable>:
Action
else:
Action après la fin de la boucle sauf si boucle interrompue par break
Functions
- Passage d'argument : toujours par valeur de la référence sur un objet (= adresse pointé)
- arguments are passed using call by value (where the value is always an object reference, not the value of the object
- Params avec valeur par défaut :
def func(p1, p2=4, p3="abc"):
- Appel avec "Keyword argument" (= passage par keyword):
- Permet de nommer explicitement les args lors de l'appel
- Nom de l'arg doit correspondre au nom du param + type dans la définition
- ex:
def print_keyword(a, b, c):
pass
print_keyword(c="this is c", a="this is a", b="b")
- Calling convention = Spécification des paramètres avec / et *:
- Présents dans la définition des paramètres
/
:
- indique que ce qui précède est un passage par position uniquement
- Ce qui suit est une définition d'un passage par position ou keyword (= par défaut si / et * absents)
*
: Indique que ce qui suit est une définition d'un passage par keywork uniquement
- "For an API, use positional-only to prevent breaking API changes if the parameter’s name is modified in the future"
def test(a, b, c, /, d, e, f, *, g, h, i):
- Liste d'arguments variables:
- Définition:
def func(*args):
- args
est une séquence
- Doit être le dernier argument de la définition sauf si keyword args qui doivent être après
- Expression Lambda:
- = fonction anonyme
- Définis par une expression "simple"
- Retourne l'évaluation de l'expression lorsqu'elle est executée
lambda <param>: <expr>
, ex: lambda x : x+1
- Appel de fonction:
- Unpacking :
*
sur une variable la split en autant de variable qu'il y a d'élément dans la séquence :
args = [1, 2, 3]
range(*args)
- Loading:
- The local namespace for a function is created when the function is called, and deleted when the function returns or raises an exception that is not handled within the function
- Recursive invocations each have their own local namespace
Class
- Propriétés:
- It is important to realize that scopes are determined textually:
- the global scope of a function defined in a module is that module’s namespace
- no matter from where or by what alias the function is called
- If no global or nonlocal statement is in effect – assignments to names always go into the innermost scope
- The global statement can be used to indicate that particular variables live in the global scope and should be rebound there;
- The nonlocal statement indicates that particular variables live in an enclosing scope and should be rebound there
- When a class definition is entered, a new namespace is created, and used as the local scope
- When a class definition is left normally (via the end), a class object is created
- Définition:
class <nom>:
# Properties (déclarée ici, elles seront communes à chaque instance) => = class variable
prop1 = value
# Constructeur:
def __init__(self, arg1, arg2, argN):
self.prop2 = value
# Properties (déclarée ici, elles seront uniques à chaque instance) => = instance variable
- Properties:
- Data attributes need not be declared, they spring into existence when they are first assigned to
- Convention de nommage: préfixe
"_"
indique que la propriété est considéré privée
- Methods:
- Python raises an exception when a function that requires an argument is called without any even if the argument isn’t actually used
- The instance object is passed as the first argument of the function (automatically)
- The first argument of a method is called self. This is nothing more than a convention
- Methods may reference global names in the same way as ordinary functions:
- The global scope associated with a method is the module containing its definition
- Convention de nommage: préfixe
"_"
indique que la méthode est considéré privée
- Instance:
x = nomClass()
- Les propriétés sont uniques à chaque instance
- Classe static:
- Les propriétés sont partagées par toutes les instances de la classe
- If the same attribute name occurs in both an instance and in a class, then attribute lookup prioritizes the instance
- Héritage:
- Définition:
class <nom>(<nom base 1>, <nom base 2>, <nom base N>):
- may override methods of their base classes (all methods in Python are effectively virtual)
- Appel méthode classe de base:
BaseClassName.methodname(self, arguments)
- Built-in
isinstance(obj, type)
: check le type d'un objet
- Buit-in
issubclass(type1, type2)
: check si type1 est dérivé de type2
- The search for attributes inherited from a parent class as depth-first, left-to-right
Module
- Définition:
- Nom de fichier + extension py
- Le nom de fichier détermine le nom du module
- The module name is available within the module by using
__name__
built-in variable
- Import :
import modname
- ajoute les définitions publics aux symboles globaux (importe le nom du module en variable)
- Accès aux défintions via
modname.def
(ou alias.def
)
from modname import def1, def2…
- ajoute aux symboles globaux uniquement les définitions mentionnées (n'importe pas le nom du module mais juste le nom definition)
- Accès aux definitions via def1, def2 etc…
from modname import *
- importe toutes les définitions sauf celles commençant par
_
[from modename] import [modname|def] as alias
- créé un alias dans les symboles globaux pour les définitions
- Run depuis ligne de commande:
- Import depuis la ligne de commande
py modname.py
: exécute le module comme un script (run les statements du code)
- Codage du main:
- Permet d'avoir un module avec code spécifique s'il est executé plutôt qu'inclus en lib
- Loading:
- Recherche le module correspondant dans les built-in
- Si pas trouvé, cherche dans les répertoires retournés par
sys.path
(répertoire local, répertoires var env PYTHONPATH
)
- The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits
- Compiled module :
- Le module est compilé lorsqu'il est importé
- Il est mis en cache dans le rep
__pycache__
du rep courant
- Ce cache permet de charger le module plus rapidement s'il n'a pas changé (modification date)
- La version compilé est plateforme-independant
- Standard modules :
- Some already built into the interpreter
dir(modname)
: retourne tous les noms définis par le module
- Module
sys
est présent dans toute implem (Windows, Linux)
- Module
builtins
: contient les modules embarqués par défaut lors de import builtins
- Pas besoin de l'importer car déjà builtin sauf si besoin de lister les déf avec dir()
Package
- = équivalent d'un namespace
- Permet de structurer plusieurs modules dans une arborescence de répertoire du FS et à l'usage de n'utiliser que celui dont on a besoin
- Le répertoire de base doit contenir le fichier
__init__.py
- Par default le fichier peut être vide
- Il peut aussi contenir une routine d'init
- Ex :
/test/__init.py
/test/poc/abc.py
- Import :
- D'un sous module ou d'une définition en particulier:
import test.poc.abc
- Chaque token du chemin doit être un module, sauf le dernier qui peut être une def
from test.poc import abc
- De toutes les def d'un module:
from package-name.sous-package import *
- Définir la variable
__all__
dans __init__.py
du package ou sous package:
- Liste le nom des modules importable du package
- Doit être mis à jour en fonction de l'ajout/suppression de modules
- Est lu par l'interpreteur lors de
import *
- Chaque package et sous-package doit posséder un
__init__.py
à jour avec la liste des modules et package qu'il possède
- Loading: The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted
Native Data Types
- Dictionnary:
- Collection indexed by keys
- The key should be of immutable type + numbers
- Constructeurs :
{}
ou { k1: val1, k2: val2… }
ou dict()
del dict[k]
=> supprime l'entrée
Key in/not in dict
=> test si la clé existe
- Comprehension is supported as it is for List =>
{ x: x**2 for x in range(10) }
- Itération:
for k, v in dict:
- List:
- Mutable
- Concat =
var + [<values>]
- "List Comprehensions" :
- Est un moyen de créer une liste selon le résultat d'une expression
- Utile pour créer une liste à partir d'une autre en ajoutant des modifs
[ expr condition ]
- Condition = autres for sur intérable & if imbriqués
[ x**2 for x in range(3) ]
=> [0, 1, 4]
Expr = x**2
- Condition =
for x in range(3)
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
=> [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
del var[index]
=> delete an entry in the list by it's index position
- Set:
- Unordered elements without duplicated elements
- Constructeurs :
{ val1, val2… }
(valeurs obligatoires autrement c'est un Dictionnary) ou set()
- Comprehension is supported as it is for List
- Tester la présence d'un élément:
valeur in var-set
- String:
- Immutable
- Indice : 0 à len-1, 0 à -len+1 => str = "abc", str[-1] = c
- entre
"
ou '
r
devant une chaine n'interprète pas les caractères spéciaux
- Concat :
+
, * (3 * <chaine> = répète)
, "abc" "def"
- Substring (= slice) :
Var[indice debut:indice fin]
- Indice début = inclus
- Indice fin = exclus
var[1:7], var[:3], var [3:]
- Tuple:
- Est immuable mais peut contenir des objets qui sont eux mutable
var = val1, val2, val3…
var[0]
=> retourne val1
- Taille d'un tuple:
len(var)
Errors & Exceptions
- Syntax Errors:
- = parsing error
- The error is caused by (or at least detected at) the token preceding the arrow
- Exception:
- = execution error
- Type of exception is printed (for built-in exception)
- Déclancher une exception volontairement:
raise
- Dans une clause
except
permet de redéclancher l'exception pour le niveau supérieur
raise ExceptionType(value)
(peut être une instance ou une classe)
- If an exception class is passed, it will be implicitly instantiated by calling its constructor with no arguments
- User-defined exception:
- Doit dériver de la classe Exception
- Handling:
try: / except:
syntaxe
- Si type de l'exception non-catché, remonte la chaine de try supérieure jusqu'à sortir du programme en unhandled exception
finally:
- code toujours executé
- Si l'exception n'était pas gérée jusque là, elle est redéclanché après le finally
#
# Syntaxe 1
#
try:
Statement
except (ExceptionType[, …]):
Handling
else:
executed statement if no exception…
finally:
always executed statement
#
# Syntaxe 2
#
try:
Statement
except Exception1 [as varname]:
Handling
except Exception2 [as varname]:
Handler
except:
Other exceptions handler
else:
executed statement if not exception…
finally:
always executer statement