Outils pour utilisateurs

Outils du site


aidememo:aide_memoire

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 :
  1. modules internes (buit-in)
  2. 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 humaine
  • repr() : représentation “machine”
  • srt.rjust() .ljust() .center() : justification du texte
  • srt.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() et list(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 str
  • json.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

aidememo/aide_memoire.txt · Dernière modification: 2019/01/11 16:14 par rguyader