Table des matières
Aide mémoire Python – 2016
Subtilités
- Les chaines sont imutables.
- Les listes sont mutable.
- “range()” est un iterable (print(range(10)) donne : range(0, 10))
- Ordre de recherche / champs des variables : look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names
- Une fonction copie les arguments en variables locales, sauf les listes. Cependant, les arguments par défaut ne sont évalués qu'une seule fois (⇒ liste par défaut persistante). Si l'on veut éviter ce comportement, faire une RAZ :
def f(a, L=None): if L is None: L = [] L.append(a) return L
Quoting :
- Double quote > simple quote
- Sur lignes multiples (docstrings) :
""" commentaire
sur
plusieurs
lignes """
- Unlike other languages, special characters such as \n have the same meaning with both single ('…') and double (“…”) quotes. The only difference between the two is that within single quotes you don’t need to escape “ (but you have to escape \') and vice versa.
Chaines :
- Opération : + et * fonctionnent
- Concaténation sans opérateur : “un” “deux” ⇒ undeux /!\ ne fonctionne pas avec des variables
- Indexation : index de départ 0 , si chiffre négatif, on commence par la droite (-1)
- Découpe : voir listes (même comportement)
- Longueur : len(<string>)
- /!\ les chaines ne supportent pas la modification
- print('The value of i is', i) : espace ajouté : The value of i is 65536
- Fin de ligne : print(b, end=',')
- Un caractère peut être utilisé pour joindre des chaines :
def concat(*args, sep="/"): return sep.join(args) concat("earth", "mars", "venus") # 'earth/mars/venus' concat("earth", "mars", "venus", sep=".") # 'earth.mars.venus'
- strip : virer les espaces à la fin
'tea for too'.replace('too', 'two') # 'tea for two'
Variables :
- Les chaines ne peuvent pas être modifiées
- L'assignement multiple est possible :
a, b = 0, 1 a, b = b, a+b
Boucles de contrôle :
while
a, b = 0, 1 while b < 10: print(b) a, b = b, a+b while True: (utiliser ensuite return True/False dans les tests)
if
if x < 0: x = 0 print('Negative changed to zero') elif x == 0: print('Zero') elif x == 1: print('Single') else: print('More')
for
words = ['cat', 'window', 'defenestrate'] for w in words: print(w, len(w)) for w in words[:]: # Loop over a slice copy of the entire list. if len(w) > 6: words.insert(0, w)
for/else
# else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs # nombres premiers de 2 à 10 for n in range(2, 10): for x in range(2, n): if n % x == 0: print(n, 'equals', x, '*', n//x) break else: #loop fell through without finding a factor print(n, 'is a prime number')
for/continue
continue force to continue next for iteration for num in range(2, 10): if num % 2 == 0: print("Found an even number", num) continue print("Found a number", num)
pass
Ne sert à rien sauf à meubler syntaxiquement
while True: pass # Busy-wait for keyboard interrupt (Ctrl+C) class MyEmptyClass: pass def initlog(*args): pass # Remember to implement this!
Itérateurs
range range(5) # 0 through 4 (5 values) range(5, 10) # 5 through 9 range(0, 10, 3) # 0, 3, 6, 9 range(-10, -100, -30) # -10, -40, -70 list(range(5)) # donne [0, 1, 2, 3, 4]
Structures de données
Listes
Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5] Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4] +---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3] | a | b | c | d | e | f | a[5]==5 a[1:2]==[1] +---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4] Slice from front: : 1 2 3 4 5 : a[-2]==4 Slice from rear: : -5 -4 -3 -2 -1 : b=a[:] b==[0,1,2,3,4,5] (shallow copy of a)
- a[:i] + a[i:] is always equal to a omitted first index defaults to zero
- omitted second index defaults to the size of the list being sliced
- out of range slice indexes are handled gracefully when used for slicing
- concatenation : +
- append : <list>.append(<value>) - equivalent à : result = result + [a]
- insert : <list>.insert(<position>,<value>)
- lists are mutable
- length : len(<list>)
- replace/remove/clear :
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] letters[2:5] = ['C', 'D', 'E'] letters[2:5] = [] letters[:] = []
- nesting possible (lists of lists), making multidimansional array : x[0][1]
- test de présence dans liste : in ; exemple : if <variable> in <list, ex : ('y', 'ye', 'yes')>
Tuples
*name unpack : args = [3, 6] list(range(*args)) # call with arguments unpacked from a list [3, 4, 5]
Dictionnaires
name keys = sorted(name.keys()) for kw in keys: print(kw, ":", name[kw])
RQ : si pas trié, alors l'ordre est indéfini
unpack : d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} function(**d)
Fonctions
def fib2(n): """Return a list containing the Fibonacci series up to n.""" result = [] a, b = 0, 1 while a < n: result.append(a) # see below a, b = b, a+b return result f100 = fib2(100) # call it f100 # write the result # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Rq documentation : La ligne de commentaire doit décrire de manière succincte le but de la fonction. Commencer par une majuscule et finir par un point. Si plus de ligne, laisser une vide.
def my_function(): """Do nothing, but document it. No, really, it doesn't do anything. """ pass print(my_function.__doc__)
Fonctions avec nombre d'arguments variables :
- affectation par défaut (<prompt> est obligatoire) : def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
- affectation par keyword (voir méthode d'appel)
Méthodes d'appel :
- classique : ask_ok('OK to overwrite the file?', 2)
- keyword : ask_ok(prompt='OK to overwrite the file?', retries=2)
RQ : ordre : d'abord les arguments sans keyword, puis les args avec keyword sinon erreur
- tuples et dictionnaires : *name, name (attention, tuples avant dictionnaires !)
RQ : les arguments qui suivent des tuples doivent avoir un keyword
fonctions anonymes : lambda
def make_incrementor(n): return lambda x: x + n f = make_incrementor(42) f(0) # 42 f(1) # 43 pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] pairs.sort(key=lambda pair: pair[1]) pairs # [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
- lambda : facilité de visualisation, un peu batard entre les macros et les fonctions
- lambda : pas une macro,
- il faut reconnaitre la syntaxe
- pour les “petits boulots”
Gestion d'erreurs
Gestion des exceptions
On peut réagir à plusieurs exceptions en même temps : except (RuntimeError, TypeError, NameError) :
try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err: print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except: # catch all print("Unexpected error:", sys.exc_info()[0]) # affiche l'exception raise # et la remonte else: print("result is", result) finally: print('Goodbye, world!') # clause toujours exécutée (avant de lever l'exception si présente) - fermer les IO ici :)
On peut lever soi-même des exceptions :
raise NameError('HiThere')
Coder proprement
- Use 4-space indentation, and no tabs.
- Wrap lines so that they don’t exceed 79 characters
- Use blank lines to separate functions and classes, and larger blocks of code inside functions.
- When possible, put comments on a line of their own.
- Use docstrings (”“”)
- Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).
- CamelCase for classes and lower_case_with_underscores for functions and methods
- Always use self as the name for the first method argument
- use ASCII of if needed UTF8
Data structures :
list
- append, extend (ajouter des éléments d'une autre liste), insert, remove, pop, clear, index, count, sort, reverse, copy, del
- Les listes peuvent être utilisées comme FIFO ou LIFO
- Pour une LIFO, utiliser de préférence deque (from collections import deque)
- list comprehesion : les éléments assignés à uni liste peuvent petre remplacées par un bout de code avec for et if, ex : [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
tuples
- Des valeurs séparées par des virgules, ex : t = 12345, 54321, 'hello!'
- Les tuples sont immuables (immutables)
- packing/unpacking supporté : x, y, z = t
- attention : pour 1 et 2 éléments :
empty = () singleton = 'hello',
sets
- collection non ordonnée, sans éléments dupliqués et support les opérations : union, intersection, difference, and symmetric difference
- basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
- attention : pour 1 élément : a = set('abracadabra')
- RQ : le même principe que 'list comprehesion' s'applique aux sets
dictionnaires
- Tableau assossiatif : tel = {'jack': 4098, 'sape': 4139}
- La clef doit être immuable et unique
Modules
- Fichiers <name>.py
- On s'en sert avec : “import <name>”
- On se sert des fonctions avec : <name>.fonction(<vars>)
- Les variables gobales sont limitées au module sémantiquement (private symbol table), elles sont aussi modifiables à l'extérieur : <name>.<var> = <newvalue>, elles sont affectées uniquement au 1er import
- On peut aussi importer directmeent des fonctions et s'en servir :
from fibo import fib fib(500)
- On peut aussi exécuter des modules comme des scripts :
python fibo.py <arguments>
Dans ce cas pour gérer les varibles, on utilise :
if __name__ == "__main__": import sys fib(int(sys.argv[1]))
RQ : on peut aussi exécuter un module directement en ligne de commande :
python fibo.py 50
- Chemin de recherche des modules :
- modules internes (buit-in)
- chemin (sys.path. sys.path) construit avec :
- répertoire du script exécuté (si symlink, c'est le répertoire final cible qui est pris en compte) si présent ou par défaut répetoire courant
- variable d'environnement PYTHONPATH
- le répertoire par défaut lié à l'installation (libs python)
Packages
Ensemble de modules Exemple : A.B désigne le sous-module B du package A
sound/ Top-level package
__init__.py Initialize the sound package formats/ Subpackage for file format conversions
__init__.py wavread.py wavwrite.py
“init.py” est nécessaire pour que le répertoire soit interprété comme contenant un package Exemple :
import sound.formats.wavread
équivalent à :
from sound.formats import wavread
- RQ : avec le formalisme from, on peut se passer du préfixe du package :
wavread.play(<file>)
- RQ : on peut aussi importer une fonction : from sound.formats.wavread import play
- RQ : from package import item permet d'importer un un package (=sous-module), un package, ou quelque chose définit comme une fonction, une classe ou une variable
- Pour “import *” : voir all dans init.py
- RQ : c'est mieux d'importer uniquement un sous-module sauf si le sous-module a des dépendances internes au package
input/output
str()
: représentation humainerepr()
: représentation “machine”srt.rjust()
.ljust() .center() : justification du textesrt.format()
: remplacement par variables dans une chaine :
print('We are the {} who say "{}!"'.format('knights', 'Ni'))
{1}
: référence par position :
print('{1} and {0}'.format('spam', 'eggs'))
{varname}
: référence indirecte :
print('This {food} is {adjective}.'.format(food='spam', adjective='absolutely horrible'))
{format}
: une conversion peut être appliquée avant formattage :
print('The value of PI is approximately {0:.3f}.'.format(math.pi))
open()
: ouvre un fichier et renvoie un objet de type fichier :
f = open('workfile', 'w')
attention à ouvrir les fichiers binaires avec l'option b en plus pour le mode !!
f.read(size)
f.readline()
for line in f: print(line, end='')
f.readlines()
etlist(f)
: lire toutes les lignes d'un coup
f.write() : value = ('the answer', 42) s = str(value) f.write(s)
tell/seek
f.close()
: fermer le fichier
formalisme with :
with open('workfile', 'r') as f: read_data = f.read() f.closed True
json
json.dumps([1, 'simple', 'list'])
: affiche la sérialisation en strjson.dump(x, f) / x = json.load(f)
: sérialiser et déserialiser dans un fichier f- Pour des instances d'objet, il y a du travail à faire en plus
pickle
: sérialisation/désérialisation d'objets : attention à la sécu !!!
Les objets
- Ils sont passés par alias (pointeurs) dans les arguments de fonctions.
- Priorité de recherche dans le scope :
the innermost scope, which is searched first, contains the local names the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names the next-to-last scope contains the current module’s global names the outermost scope (searched last) is the namespace containing built-in names
- Par defaut les variables sont locales
- nonlocal : référence la variable à la variable du même nom dans le scope le plus proche
- global : la variable fait partie du scope global
- une classe est un objet et possède son namespace spécifique
Exemple : attribute references :
class MyClass: """A simple example class""" i = 12345 # attribute def f(self): # method return 'hello world'
Exemple : instantiation :
x = MyClass()
init :
def __init__(self):
- On peut créer de nouveaux attributs dans les instances objets (les objets sont “dynamiques”)
- Par defaut les variables déclarées dans une classe sont communes à toutes les instances
- Pour faire des variables locale aux instances, il faut les déclarer dans init
- Les attributs privés à la classe n'existent pas, mais par convention on les nomme :
_<nomvar>
- Pour protéger des variables ou des fonctions utilisées en interne dans une classe, on instancie une copie locale que l'on nomme <nom attribut ou methode>
RQ : les variables écrasent les fonctions dans les instances, il faut utiliser une convention
- héritage :
class DerivedClassName(BaseClassName):
- héritage multiple :
class DerivedClassName(Base1, Base2, Base3):
outils :
isinstance(objet, instance) issubclass(sousclasse, classe)
iterateur : iter()
et next()
:
class Reverse: """Iterator for looping over a sequence backwards.""" def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] class.attribute class.attribute = 6 del class.attribute class MyClass: """A simple example class""" kind = 'canine' # class variable shared by all instances def __init__(self, realpart, imagpart): self.name = name # instance variable unique to each instance def f(self): return 'hello world' x = MyClass() x.f()
Si variable ou fonction est précédée de
__
alors elle est privée
Yield, générateur et generator expressions
générateur : iter()
et next()
sont générés automatiquement :
def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] for char in reverse('golf'): print(char, "") sum(i*i for i in range(10)) # sum of squares 285 xvec = [10, 20, 30] yvec = [7, 5, 3] sum(x*y for x,y in zip(xvec, yvec)) # dot product 260 from math import pi, sin sine_table = {x: sin(x*pi/180) for x in range(0, 91)} unique_words = set(word for line in page for word in line.split()) valedictorian = max((student.gpa, student.name) for student in graduates) data = 'golf' list(data[i] for i in range(len(data)-1, -1, -1)) ['f', 'l', 'o', 'g']
Standard library :
module os
Intéragir avec l'OS
import os os.getcwd() # Return the current working directory os.system('mkdir today') # Run the command mkdir in the system shell dir(os) # returns a list of all module functions help(os) # returns an extensive manual page created from the module's docstrings
module shutils
File and dir managment
import shutil shutil.copyfile('data.db', 'archive.db') shutil.move('/build/executables', 'installdir')
module glob
Wilcard file listing
import glob glob.glob('*.py') # ['primes.py', 'random.py', 'quote.py']
module sys
Entre autre pour les arguments du programme, les sorties d'erreur, la sortie de programme
import sys print(sys.argv) # ['demo.py', 'one', 'two', 'three'] sys.stderr.write('Warning, log file not found starting a new one\n') sys.exit()
RQ : The getopt module processes sys.argv using the conventions of the Unix getopt() function. More powerful and flexible command line processing is provided by the argparse module.
module re
Regexp
import re re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') # ['foot', 'fell', 'fastest'] re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') # 'cat in the hat'
module math
Librairies c pour virgule flotante
import math math.cos(math.pi / 4) # 0.70710678118654757 math.log(1024, 2) # 10.0
module random
Selections aléatoires
import random random.choice(['apple', 'pear', 'banana']) # 'apple' random.sample(range(100), 10) # sampling without replacement : [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] random.random() # random float : 0.17970987693706186 random.randrange(6) # random integer chosen from range(6) : 4
modules urllib / smtplib
Récupérer des infos depuis des urls, envoyer des mails
module datetime
zlib
timeit, profile, pstats
outil de mesure interne
doctest, unittest
contrôle qualité : tests,
reprlib
version de repr spécifique pour l'abréviation des nested containers
pprint
plus de contôle sur l'affichage, affiche les structures et objets de manière lisible
textwarp
formatage de paragraphes
locale
accès aux formats spécifiques selon la culture (langue/géographie)
string
from string import Template :
from string import Template t = Template('${village}folk send $$10 to $cause.') t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.' Voir aussi substitute, safe_substitute, propriété delimiter