modifs apres la formation a Nantes
This commit is contained in:
parent
cdaba77a67
commit
e3efe7d917
0
modules_EOLE_envole/documents/tronc-commun-2/posttemplate/00-creation
Executable file → Normal file
0
modules_EOLE_envole/documents/tronc-commun-2/posttemplate/00-creation
Executable file → Normal file
|
@ -21,8 +21,102 @@ le comportement d'un :term:`objet` :
|
||||||
|
|
||||||
envois de messages à l'objet = appel de **méthodes**
|
envois de messages à l'objet = appel de **méthodes**
|
||||||
|
|
||||||
classes d'objets
|
programmation objet (première approche)
|
||||||
------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
- le type et le protocole d'un objet sont définis par sa classe
|
||||||
|
- une classe possède un ensemble d'attributs et de méthodes
|
||||||
|
|
||||||
|
deux relations possibles
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
.. glossary::
|
||||||
|
|
||||||
|
heritage
|
||||||
|
|
||||||
|
relation "est une espèce de " utilisée entre une classe et une autre classe
|
||||||
|
|
||||||
|
instantiation
|
||||||
|
|
||||||
|
relation "est une instance de " entre un objet et une classe
|
||||||
|
|
||||||
|
|
||||||
|
- est une instance de (objets par rapport à classe)
|
||||||
|
- est une espèce de (classe par rapport à classe, :term:`heritage`)
|
||||||
|
|
||||||
|
**instance**
|
||||||
|
|
||||||
|
- définition d'une classe
|
||||||
|
- instance de classe : on peut créer des objets à partir d'un type "classe"
|
||||||
|
(une classe est instanciable)
|
||||||
|
|
||||||
|
>>> class A:
|
||||||
|
... pass
|
||||||
|
...
|
||||||
|
>>> a = A()
|
||||||
|
|
||||||
|
:term:`heritage` : notation en python
|
||||||
|
|
||||||
|
>>> class A: pass
|
||||||
|
...
|
||||||
|
>>> class B(A): pass
|
||||||
|
...
|
||||||
|
>>> b = B()
|
||||||
|
>>> type(b) == B
|
||||||
|
>>> isinstance(b, A) == True
|
||||||
|
|
||||||
|
possibilité en python d'héritage multiple::
|
||||||
|
|
||||||
|
class A(B, C): pass
|
||||||
|
|
||||||
|
|
||||||
|
introspection contre encapsulation
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
voir un objet comme un espace de nommage. C'est plus **agile**.
|
||||||
|
|
||||||
|
attributs et méthodes vus comme des ajouts dans l'espace de nommage
|
||||||
|
|
||||||
|
>>> a.a = 2
|
||||||
|
>>> def function(x):
|
||||||
|
... print x
|
||||||
|
...
|
||||||
|
>>> a.f = function
|
||||||
|
>>> a.f("hello")
|
||||||
|
hello
|
||||||
|
>>>
|
||||||
|
|
||||||
|
|
||||||
|
la nécessité d'un design objet
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
affichage d'une calculette, il faut créer un type `Touche`
|
||||||
|
qui contient deux désignations : `Chiffre` et `operation`::
|
||||||
|
|
||||||
|
type operation = Plus | Moins | Divise
|
||||||
|
type touche = Chiffre of int | Memoire | Op of operation
|
||||||
|
|
||||||
|
soit, on définit un type touche, soit on ne définit pas ce type::
|
||||||
|
|
||||||
|
type operation = Plus | Moins | Divise
|
||||||
|
type memoire = Memoire
|
||||||
|
type chiffre = Chiffre
|
||||||
|
|
||||||
|
- les structures de données (int, str, list, dict...) : types de base
|
||||||
|
- les structures de données utilisateur : les classes !
|
||||||
|
|
||||||
|
.. function:: type (objname)
|
||||||
|
|
||||||
|
:param objname: l'objet dont on veut connaître le type
|
||||||
|
|
||||||
|
Manipulations sur les classes et les objets
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
En python un type et une classe c'est la même chose. Une classe
|
||||||
|
est un type standard. En python tout est objet, et tout provient d'un seul objet
|
||||||
|
(qui s'appelle ``object``).
|
||||||
|
|
||||||
- encapsulation (cacher les attributs (variables d'état)) d'un objet.
|
- encapsulation (cacher les attributs (variables d'état)) d'un objet.
|
||||||
|
|
||||||
|
@ -32,10 +126,10 @@ Une interface décrit un ensemble de comportements.
|
||||||
on peut considérer une interface comme un protocole d'utilisation d'un objet
|
on peut considérer une interface comme un protocole d'utilisation d'un objet
|
||||||
dans un contexte donné.
|
dans un contexte donné.
|
||||||
|
|
||||||
On peut alors créer des outils qui sauront traiter n'importe quel objet
|
on peut alors créer des outils qui sauront traiter n'importe quel objet
|
||||||
pourvu qu'il respecte un ensemble d'interfaces.
|
pourvu qu'il respecte une ensemble d'interfaces.
|
||||||
|
|
||||||
.. todo:: travailler l'héritage, l'agrégation, la délégation
|
.. todo:: travailler l'héritage, l'aggrégation, la délégation
|
||||||
|
|
||||||
Voici un exemple de classe `Voiture` :
|
Voici un exemple de classe `Voiture` :
|
||||||
|
|
||||||
|
@ -159,3 +253,12 @@ AttributeError: O instance has no attribute 'u'
|
||||||
>>> f.attr
|
>>> f.attr
|
||||||
'decorated'
|
'decorated'
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
autre exemple : les méthodes statiques
|
||||||
|
|
||||||
|
>>> class A(object):
|
||||||
|
... @staticmethod
|
||||||
|
... def my_class_method(cls):
|
||||||
|
... # do stuff here
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,19 @@ L'objectif de ce cours est de vous apprendre à programmer en
|
||||||
:term:`python`. Ce cours a été fait avec :term:`sphinx`, l'outil de
|
:term:`python`. Ce cours a été fait avec :term:`sphinx`, l'outil de
|
||||||
gestion de documentation en python utilisé pour documenter python lui-même.
|
gestion de documentation en python utilisé pour documenter python lui-même.
|
||||||
|
|
||||||
Avec python :
|
avec python :
|
||||||
|
|
||||||
- vous n'avez pas grand chose à savoir pour arriver à faire beaucoup de choses ;
|
- vous n'avez pas grand chose à savoir pour arriver à faire beaucoup de choses,
|
||||||
|
|
||||||
- vous allez pouvoir travailler de manière :
|
- vous allez pouvoir travailler de manière
|
||||||
|
|
||||||
- entièrement autonome ;
|
- entièrement autonome
|
||||||
- rapide ;
|
- rapide
|
||||||
- agile (au sens des méthodes agiles) ;
|
- agile (au sens des méthodes agiles)
|
||||||
|
|
||||||
- vous allez progresser rapidement ;
|
- vous allez progresser rapidement
|
||||||
|
|
||||||
- aucune connaissance préalable en programmation n'est requise ;
|
- aucune connaissance préalable en programmation n'est requise
|
||||||
|
|
||||||
- le hello world en une ligne::
|
- le hello world en une ligne::
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ Avec python :
|
||||||
- lorsqu'on lance python sans spécifier de nom de fichier, c'est l'interpréteur
|
- lorsqu'on lance python sans spécifier de nom de fichier, c'est l'interpréteur
|
||||||
python qui est lancé (le "prompt")
|
python qui est lancé (le "prompt")
|
||||||
|
|
||||||
Taper "python" dans votre console.
|
Taper "python" dans votre console
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -72,20 +72,20 @@ Taper "python" dans votre console.
|
||||||
les modules, :ref:`namespaces` et la librairie standard
|
les modules, :ref:`namespaces` et la librairie standard
|
||||||
:doc:`stdlib`
|
:doc:`stdlib`
|
||||||
|
|
||||||
Pour avoir de l'aide, taper dans le prompt :
|
pour avoir de l'aide, taper dans le prompt :
|
||||||
|
|
||||||
>>> help(function)
|
>>> help(function)
|
||||||
|
|
||||||
Usage de python
|
usage de python
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
À peu près tous les domaines de l'informatique, du scripting système à la génération
|
à peu près tous les domaines de l'informatique, du scripting système à la génération
|
||||||
de pdf en passant par le développement web et le développement rapide d'applications.
|
de pdf en passant par le développement web et le développement rapide d'applications.
|
||||||
|
|
||||||
|
|
||||||
exemple : web server
|
exemple : web server
|
||||||
|
|
||||||
Pour créer un serveur web simplement::
|
pour créer un serveur web simplement::
|
||||||
|
|
||||||
python -m SimpleHTTPServer 8000 localhost
|
python -m SimpleHTTPServer 8000 localhost
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ apprentissage de la programmation avec python
|
||||||
settings
|
settings
|
||||||
type
|
type
|
||||||
structures
|
structures
|
||||||
prompt
|
testsunitaires
|
||||||
|
|
||||||
|
|
||||||
programmation python, connaissances de base
|
programmation python, connaissances de base
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
@ -17,9 +18,9 @@ programmation python, connaissances de base
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
classes
|
classes
|
||||||
|
prompt
|
||||||
specialmethods
|
specialmethods
|
||||||
stdlib
|
stdlib
|
||||||
testsunitaires
|
|
||||||
|
|
||||||
Index et recherche
|
Index et recherche
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Interactions avec l'utilisateur
|
Interactions avec l'utilisateur
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
Les prompts
|
les prompts
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
`raw_input` ou `input`
|
`raw_input` ou `input`
|
||||||
|
@ -14,10 +14,10 @@ Les prompts
|
||||||
|
|
||||||
.. _cmdlabel:
|
.. _cmdlabel:
|
||||||
|
|
||||||
Le module :mod:`cmd` et les interpréteurs
|
le module :mod:`cmd` et les interpréteurs
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
Le monde des interpréteur ligne de commande...
|
le monde des interpréteur ligne de commande...
|
||||||
|
|
||||||
Peu après l'âge de bronze vint le temps de l'interpréteur ligne de commande,
|
Peu après l'âge de bronze vint le temps de l'interpréteur ligne de commande,
|
||||||
c'est-à-dire quelque chose de plus spécifique que **l'application ligne de commande**,
|
c'est-à-dire quelque chose de plus spécifique que **l'application ligne de commande**,
|
||||||
|
@ -26,18 +26,18 @@ ou que l'utilitaire ligne de commande.
|
||||||
|
|
||||||
Un interpréteur ligne de commande est un programme qui :
|
Un interpréteur ligne de commande est un programme qui :
|
||||||
|
|
||||||
- est forcément plein texte ;
|
- est forcément plein texte
|
||||||
- vous donne un prompt ;
|
- vous donne un prompt
|
||||||
- prend toutes ses entrées d'un coup ;
|
- prends toutes ses entrées d'un coup
|
||||||
- produit une sortie (typiquement des lignes de texte) ;
|
- produit une sortie (typiquement des lignes de texte)
|
||||||
- vous redonne un prompt.
|
- vous redonne un prompt
|
||||||
|
|
||||||
Le shell unix est un bon exemple d'interpréteur ligne de commande.
|
Le shell unix est un bon exemple d'interpréteur ligne de commande.
|
||||||
|
|
||||||
Un utilitaire ligne de commande est un programme unix-like qui prend toutes
|
Un utilitaire ligne de commande est un programme unix-like qui prend toutes
|
||||||
les entrées d'un coup, et qui vous renvoie une sortie d'un coup.
|
les entrées d'un coup, et qui vous renvoie une sortie d'un coup.
|
||||||
|
|
||||||
Le module :mod:`cmd` : exemple d'utilisation
|
le module :mod:`cmd` : exemple d'utilisation
|
||||||
|
|
||||||
.. module:: cmd
|
.. module:: cmd
|
||||||
:synopsis: interpréteur ligne de commande
|
:synopsis: interpréteur ligne de commande
|
||||||
|
@ -65,8 +65,7 @@ Le module :mod:`cmd` : exemple d'utilisation
|
||||||
|
|
||||||
#Prompt>
|
#Prompt>
|
||||||
|
|
||||||
Pour ajouter une commande, utilisez juste l'héritage::
|
pour ajouter une commande, utiliser simplement l'héritage::
|
||||||
|
|
||||||
|
|
||||||
>>> from cli import Cli
|
>>> from cli import Cli
|
||||||
>>> class Prompt(Cli):
|
>>> class Prompt(Cli):
|
||||||
|
@ -92,10 +91,10 @@ Pour ajouter une commande, utilisez juste l'héritage::
|
||||||
|
|
||||||
.. todo:: faire un petit projet d'interpréteur ligne de commande du jeu C+/C-
|
.. todo:: faire un petit projet d'interpréteur ligne de commande du jeu C+/C-
|
||||||
|
|
||||||
Lire et écrire dans un fichier
|
lire et écrire dans un fichier
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
Les **handle de fichier** (file handles)
|
les **handle de fichier** (file handles)
|
||||||
|
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Mettre en place son environnement de travail
|
Mettre en place son environnement de travail
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
Un framework de développement intégré : :term:`IDLE`
|
un framework de développement intégré : :term:`IDLE`
|
||||||
|
|
||||||
.. glossary::
|
.. glossary::
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ Un framework de développement intégré : :term:`IDLE`
|
||||||
|
|
||||||
.. _`librairie standard`: http://docs.python.org/2.7/library/index.html
|
.. _`librairie standard`: http://docs.python.org/2.7/library/index.html
|
||||||
|
|
||||||
Premier réflexe : consulter la doc en ligne ou bien installée sur votre disque dur.
|
Premier réflexe : la doc en ligne ou bien installée sur votre disque dur.
|
||||||
|
|
||||||
La page d'accueil de la doc officielle python :
|
la page d'accueil de la doc officielle python :
|
||||||
|
|
||||||
.. image:: images/DocPython.png
|
.. image:: images/DocPython.png
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ modules :
|
||||||
|
|
||||||
.. image:: images/ModuleIndex.png
|
.. image:: images/ModuleIndex.png
|
||||||
|
|
||||||
Configurer son éditeur
|
configurer son éditeur
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
- les fichiers sources ont l'extenstion `.py`
|
- les fichiers sources ont l'extenstion `.py`
|
||||||
|
@ -40,7 +40,7 @@ Configurer son éditeur
|
||||||
- les blocs sont marqués par l'indentation (utilser 4 espaces), règler
|
- les blocs sont marqués par l'indentation (utilser 4 espaces), règler
|
||||||
l'éditeur pour transformer les tabulations en espaces
|
l'éditeur pour transformer les tabulations en espaces
|
||||||
|
|
||||||
Configurer son prompt python
|
configurer son prompt python
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. envvar:: PYTHONPATH
|
.. envvar:: PYTHONPATH
|
||||||
|
@ -48,14 +48,16 @@ Configurer son prompt python
|
||||||
pointe par défaut sur le répertoire courant, il est possible d'ajouter
|
pointe par défaut sur le répertoire courant, il est possible d'ajouter
|
||||||
un path
|
un path
|
||||||
|
|
||||||
À mettre dans votre `.bashrc` :
|
à mettre dans votre `.bashrc` :
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
export PYTHONPATH:`pwd`
|
export PYTHONPATH:`pwd`
|
||||||
export PYTHONPATH=$PYTHONPATH:'/usr/share':'/home/gwen/local
|
|
||||||
|
export PYTHONPATH=$PYTHONPATH:'/usr/share':'/toto/titi/tata'
|
||||||
|
|
||||||
alias pyenv='export PYTHONPATH=`pwd`:$PYTHONPATH'
|
alias pyenv='export PYTHONPATH=`pwd`:$PYTHONPATH'
|
||||||
|
|
||||||
export PYTHONSTARTUP='/home/gwen/.pystartup'
|
export PYTHONSTARTUP='/home/gwen/.pystartup'
|
||||||
|
|
||||||
.. envvar:: PYTHONSTARTUP
|
.. envvar:: PYTHONSTARTUP
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
class NotFoundError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class MaClasse:
|
class MaClasse:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class MaClasseDeux:
|
class MaClasseDeux:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
binding = dict('un'=MaClasse, 'deux'=MaClasseDeux)
|
binding = dict(un=MaClasse, deux=MaClasseDeux)
|
||||||
|
|
||||||
def ma_factory(key):
|
def ma_factory(key):
|
||||||
if key in binding:
|
if key in binding:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Wrap(object):
|
class Wrap(object):
|
||||||
def __init__(self, name, wrap):
|
def __init__(self, name, wrap):
|
||||||
self.slots = ('_name', '_wrap')
|
self.slots = ('_name', '_w')
|
||||||
self._name = name or "wrapped_element"
|
self._name = name or "wrapped_element"
|
||||||
self._w = wrap
|
self._w = wrap
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ Programmation python courante
|
||||||
|
|
||||||
.. _namespaces:
|
.. _namespaces:
|
||||||
|
|
||||||
Les espaces de nommage
|
les espaces de nommage
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Packages et modules::
|
Packages et modules::
|
||||||
|
@ -15,9 +15,9 @@ Packages et modules::
|
||||||
__init__.py
|
__init__.py
|
||||||
module2.py
|
module2.py
|
||||||
|
|
||||||
À utilser pour organiser votre projet.
|
A utilser pour organiser votre projet
|
||||||
Permet de minimiser les risques de conflits de nom.
|
Permet de minimiser les risques de conflits de nome
|
||||||
Permet de diminuer les entrées dans le :envvar:`PYTHONPATH`.
|
Permet de diminuer les entrées dans le :envvar:`PYTHONPATH`
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -35,31 +35,31 @@ Permet de diminuer les entrées dans le :envvar:`PYTHONPATH`.
|
||||||
|
|
||||||
from os import *
|
from os import *
|
||||||
|
|
||||||
Lancer un module en tant que script :
|
lance un module en tant que script :
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
Organisation modulaire :
|
Organisation modulaire
|
||||||
|
|
||||||
- construire des composants élémentaires ;
|
- construire des composants élémentaires
|
||||||
- combiner ces composants ;
|
- combiner ces composants
|
||||||
- utiliser une structure pyramidale : les composants sont les éléments de
|
- utiliser une structure pyramidale : les composants sont les éléments de
|
||||||
composants plus complexes.
|
composants plus complexes.
|
||||||
|
|
||||||
|
|
||||||
- découplage de l'ensemble en composants indépendants (gros programmes réalisables) ;
|
- découplage de l'ensemble en composants indépendants (gros programmes réalisables)
|
||||||
- donner de la structure (rendre les gros programmes compréhensibles) ;
|
- donner de la structure (rendre les gros programmes compréhensibles)
|
||||||
- spécifier les liens entre les composants (rendre les programmes maintenables) ;
|
- spécifier les liens entre les composants (rendre les programmes maintenables)
|
||||||
- identifier les sous-composants indépendants (rendre les programmes réutilisables) ;
|
- identifier les sous-composants indépendants (rendre les programmes réutilisables)
|
||||||
- forcer l'abstraction (augmenter la sureté du programme).
|
- forcer l'abstraction (augmenter la sureté du programme)
|
||||||
|
|
||||||
Les méthodes spéciales
|
Les méthodes spéciales
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Méthodes spéciales correspondant aux interfaces des types de bases :
|
méthodes spéciales correspondants aux interfaces des types de bases :
|
||||||
|
|
||||||
.. function:: __init__(self, *args, **kwargs)
|
.. function:: __init__(self, *args, **kwargs)
|
||||||
le constructeur de l'instance d'objet
|
le constructeur de l'instance d'objet
|
||||||
|
@ -106,9 +106,9 @@ aux attributs est règlable.
|
||||||
>>> cobj.__dict__['insattr']
|
>>> cobj.__dict__['insattr']
|
||||||
'an instance attribute'
|
'an instance attribute'
|
||||||
|
|
||||||
Les attributs ne sont pas systématiquement encapsulés en python.
|
les attributs ne sont pas systématiquement encapsulées en python.
|
||||||
|
|
||||||
Pour contrôler l'accès aux attributs, on utilise les méthodes spéciales::
|
pour contrôler l'accès aux attributs, on utilise les méthodes spéciales::
|
||||||
|
|
||||||
__getattr__(self, name)
|
__getattr__(self, name)
|
||||||
|
|
||||||
|
@ -134,51 +134,6 @@ Pour contrôler l'accès aux attributs, on utilise les méthodes spéciales::
|
||||||
if callable(func):
|
if callable(func):
|
||||||
func(args)
|
func(args)
|
||||||
|
|
||||||
.. todo:: émulation de defaultdict
|
|
||||||
|
|
||||||
Dict with a default value
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Il est possible d'hériter des types de base
|
|
||||||
|
|
||||||
>>> a = dict.defaultdict(default=0)
|
|
||||||
>>> a
|
|
||||||
{}
|
|
||||||
>>> a[1] = 2
|
|
||||||
>>> print a
|
|
||||||
{1: 2}
|
|
||||||
>>> a[0]
|
|
||||||
0
|
|
||||||
>>> a.keys()
|
|
||||||
[1]
|
|
||||||
>>> a["machin"]
|
|
||||||
0
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
class defaultdict(dict):
|
|
||||||
|
|
||||||
def __init__(self, default=None):
|
|
||||||
dict.__init__(self)
|
|
||||||
self.default = default
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
try:
|
|
||||||
return dict.__getitem__(self, key)
|
|
||||||
except KeyError:
|
|
||||||
return self.default
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
if key in self:
|
|
||||||
return dict.__getitem__(self, key)
|
|
||||||
else:
|
|
||||||
return self.default
|
|
||||||
|
|
||||||
def get(self, key, *args):
|
|
||||||
if not args:
|
|
||||||
args = (self.default,)
|
|
||||||
return dict.get(self, key, *args)
|
|
||||||
|
|
||||||
- un **attribut** spécial : `__slots__`
|
- un **attribut** spécial : `__slots__`
|
||||||
|
|
||||||
permet de fixer les attributs possibles d'une classe
|
permet de fixer les attributs possibles d'une classe
|
||||||
|
@ -197,6 +152,12 @@ permet de fixer les attributs possibles d'une classe
|
||||||
File "<stdin>", line 1, in ?
|
File "<stdin>", line 1, in ?
|
||||||
AttributeError: 'Bar' object has no attribute 'd'
|
AttributeError: 'Bar' object has no attribute 'd'
|
||||||
|
|
||||||
|
les slots
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. important:: l'encapsulation n'est pas une condition de base de la programmation
|
||||||
|
par objects, surtout que le contrôle nuit à l'agilité.
|
||||||
|
|
||||||
>>> class Point(object):
|
>>> class Point(object):
|
||||||
... __slots__ = 'x', 'y'
|
... __slots__ = 'x', 'y'
|
||||||
...
|
...
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
La :term:`librairie standard`
|
La :term:`librairie standard`
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
les builtins
|
||||||
|
-------------
|
||||||
|
|
||||||
.. module:: builtins
|
.. module:: builtins
|
||||||
:synopsis: les fonctions directement à disposition sans import spécifique
|
:synopsis: les fonctions directement à disposition sans import spécifique
|
||||||
|
|
||||||
|
@ -134,8 +137,7 @@ Password:
|
||||||
.. module:: shelve
|
.. module:: shelve
|
||||||
:synopsis: linéarisation de données
|
:synopsis: linéarisation de données
|
||||||
|
|
||||||
Linéarisation de données
|
- linéarisation de données
|
||||||
==========================
|
|
||||||
|
|
||||||
>>> import shelve
|
>>> import shelve
|
||||||
>>> shelve.open("database", 'c')
|
>>> shelve.open("database", 'c')
|
||||||
|
|
|
@ -60,7 +60,7 @@ deux
|
||||||
1
|
1
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
Fonctions
|
fonctions
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
>>> def blabla(x):
|
>>> def blabla(x):
|
||||||
|
@ -69,7 +69,7 @@ Fonctions
|
||||||
...
|
...
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
Il n'y a que des fonctions (et pas de procédures):
|
il n'y a que des fonctions (et pas de procédures):
|
||||||
|
|
||||||
|
|
||||||
>>> def ma_func(x):
|
>>> def ma_func(x):
|
||||||
|
@ -147,13 +147,13 @@ argumments nommés {'tata': 3, 'tutu': 2}
|
||||||
>>> vars(a)
|
>>> vars(a)
|
||||||
{'a': 'titi', 'b': 'toto'}
|
{'a': 'titi', 'b': 'toto'}
|
||||||
|
|
||||||
Puisque tout est objet en python, ``vars(mon_objet)`` est équivalent à
|
puisque tout est objet en python, ``vars(mon_objet)`` est équivalent à
|
||||||
``mon_objet.__dict__``
|
``mon_objet.__dict__``
|
||||||
|
|
||||||
|
|
||||||
- générateurs et compréhension de liste
|
- générateurs et compréhension de liste
|
||||||
|
|
||||||
Les compréhensions de listes permettent de générer de nouvelles listes
|
les compréhensions de listes permettent de générer de nouvelles listes
|
||||||
|
|
||||||
exemple :
|
exemple :
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ exemple :
|
||||||
[(2, 4), (2, 5), (2, 6), (2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (4, 4), (4, 5), (4, 6), (4, 7)]
|
[(2, 4), (2, 5), (2, 6), (2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (4, 4), (4, 5), (4, 6), (4, 7)]
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
Les expressions générateurs
|
les expressions générateurs
|
||||||
|
|
||||||
>>> expr = (2*i for i in range(10))
|
>>> expr = (2*i for i in range(10))
|
||||||
>>> expr
|
>>> expr
|
||||||
|
@ -190,10 +190,10 @@ Les expressions générateurs
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
|
||||||
Le polymorphisme paramétrique
|
le polymorphisme paramétrique
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Polymorphisme exemple de contexte :
|
polymorphisme exemple de contexte :
|
||||||
la fonction print
|
la fonction print
|
||||||
|
|
||||||
>>> print 1
|
>>> print 1
|
||||||
|
@ -203,7 +203,7 @@ la fonction print
|
||||||
|
|
||||||
.. todo:: `print 1` et `print "1"` renvoient le même résultat. Pourquoi ?
|
.. todo:: `print 1` et `print "1"` renvoient le même résultat. Pourquoi ?
|
||||||
|
|
||||||
La programmation par exceptions
|
la programmation par exceptions
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
>>> def function_raise(x):
|
>>> def function_raise(x):
|
||||||
|
@ -222,84 +222,3 @@ Pas le bon type
|
||||||
|
|
||||||
.. important:: règle du Samouraï : une fonction doit renvoyer le résultat escompté
|
.. important:: règle du Samouraï : une fonction doit renvoyer le résultat escompté
|
||||||
ou bien lever une exception
|
ou bien lever une exception
|
||||||
|
|
||||||
|
|
||||||
Programmation objet
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
- la programmation objet définit des classes
|
|
||||||
- le type et le protocole d'un objet sont définis par sa classe
|
|
||||||
- une classe possède un ensemble d'attributs et de méthodes
|
|
||||||
|
|
||||||
>>> class A:
|
|
||||||
... pass
|
|
||||||
...
|
|
||||||
>>> a = A()
|
|
||||||
>>> a.a = 2
|
|
||||||
>>> def function(x):
|
|
||||||
... print x
|
|
||||||
...
|
|
||||||
>>> a.f = function
|
|
||||||
>>> a.f("hello")
|
|
||||||
hello
|
|
||||||
>>>
|
|
||||||
|
|
||||||
- instance de classe : on peut créer des objets à partir d'un type "classe"
|
|
||||||
(une classe est instanciable)
|
|
||||||
|
|
||||||
- définition d'une classe :
|
|
||||||
|
|
||||||
Méthode classique :
|
|
||||||
|
|
||||||
>>> class A:
|
|
||||||
... pass
|
|
||||||
...
|
|
||||||
|
|
||||||
Méthode dynamique (la fonction :func:`type` est ici un **constructeur** :
|
|
||||||
|
|
||||||
>>> type("A", (), {})
|
|
||||||
<class '__main__.A'>
|
|
||||||
>>> A = type("A", (), {})
|
|
||||||
>>> a = A()
|
|
||||||
>>> type(a)
|
|
||||||
<class '__main__.A'>
|
|
||||||
|
|
||||||
Types et classe
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Affichage d'une calculette, il faut créer un type `Touche`
|
|
||||||
qui contient deux désignations : `Chiffre` et `operation`::
|
|
||||||
|
|
||||||
type operation = Plus | Moins | Divise
|
|
||||||
type touche = Chiffre of int | Memoire | Op of operation
|
|
||||||
|
|
||||||
Soit on définit un type touche, soit on ne définit pas ce type::
|
|
||||||
|
|
||||||
type operation = Plus | Moins | Divise
|
|
||||||
type memoire = Memoire
|
|
||||||
type chiffre = Chiffre
|
|
||||||
|
|
||||||
- les structures de données (int, str, list, dict...) : types de base
|
|
||||||
- les structures de données utilisateur : les classes !
|
|
||||||
|
|
||||||
.. function:: type (objname)
|
|
||||||
|
|
||||||
:param objname: l'objet dont on veut connaître le type
|
|
||||||
|
|
||||||
.. todo:: tout hérite de la classe `object`
|
|
||||||
|
|
||||||
>>> object
|
|
||||||
<type 'object'>
|
|
||||||
>>> type(object)
|
|
||||||
<type 'type'>
|
|
||||||
>>> type(type)
|
|
||||||
<type 'type'>
|
|
||||||
>>> type(type(type))
|
|
||||||
<type 'type'>
|
|
||||||
>>> isinstance(type, object)
|
|
||||||
True
|
|
||||||
>>> isinstance(object, object)
|
|
||||||
True
|
|
||||||
|
|
||||||
**conclusion** : en python un type et une classe c'est la même chose. Une classe
|
|
||||||
est un type standard !
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ Tests unitaires et pile d'appels
|
||||||
|
|
||||||
Les tests automatiques sont un complément à la déclaration des types.
|
Les tests automatiques sont un complément à la déclaration des types.
|
||||||
|
|
||||||
Que tester, quoi tester ?
|
que tester, quoi tester ?
|
||||||
|
|
||||||
- que les composants interagissent bien entre eux
|
- que les composants interagissent bien entre eux
|
||||||
- que les unités (fonctions, objets...) réagissent bien à une entrée spécifique
|
- que les unités (fonctions, objets...) réagissent bien à une entrée spécifique
|
||||||
- que le code se comporte de la manière attendue dans des environnements différents
|
- que le code se comporte de la manière attendue dans des environnements différents
|
||||||
(systèmes d'exploitation, etc...)
|
(systèmes d'exploitation, etc...)
|
||||||
|
|
||||||
Les types de tests :
|
les types de tests :
|
||||||
|
|
||||||
- tests unitaires
|
- tests unitaires
|
||||||
- tests fonctionnels
|
- tests fonctionnels
|
||||||
|
@ -52,7 +52,7 @@ http://pytest.org/latest/
|
||||||
|
|
||||||
- écrire un fichier commençant par `test_` qui teste les fonctions du fichier
|
- écrire un fichier commençant par `test_` qui teste les fonctions du fichier
|
||||||
|
|
||||||
Options utiles dans `py.test`
|
options utiles dans `py.test`
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -67,10 +67,10 @@ Options utiles dans `py.test`
|
||||||
py.test -k test_simple
|
py.test -k test_simple
|
||||||
|
|
||||||
|
|
||||||
Utiliser la pile d'appel pour débugger
|
utiliser la pile d'appel pour débugger
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
Utiliser la pile d'appels, elle se lit de bas en haut. Il est possible de
|
utiliser la pile d'appels, elle se lit de bas en haut. Il est possible de
|
||||||
provoquer cette pile d'appels.
|
provoquer cette pile d'appels.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -79,7 +79,7 @@ provoquer cette pile d'appels.
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
Traiter une exception avec
|
traiter une exception avec
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -95,9 +95,9 @@ Traiter une exception avec
|
||||||
bla bla
|
bla bla
|
||||||
|
|
||||||
|
|
||||||
Créer le plus possible ses propres exceptions spécifiques au programme.
|
créer le plus possible ses propres exceptions spécifiques au programme
|
||||||
|
|
||||||
Utiliser le module :mod:`pdb`
|
utiliser le module :mod:`pdb`
|
||||||
|
|
||||||
.. module:: pdb
|
.. module:: pdb
|
||||||
:synopsis: debugger de la lib standard
|
:synopsis: debugger de la lib standard
|
||||||
|
@ -144,7 +144,7 @@ Remarquons que :mod:`pdb` utilise le module :mod:`cmd`, voir :ref:`cmdlabel` qu'
|
||||||
(Pdb)
|
(Pdb)
|
||||||
|
|
||||||
|
|
||||||
Last but not least :
|
last but not least :
|
||||||
|
|
||||||
utiliser pylint ou pychecker
|
utiliser pylint ou pychecker
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ python est un langage dynamiquement typé. qu'est-ce que cela signifie ?
|
||||||
|
|
||||||
- ouvrir l'interpréteur python
|
- ouvrir l'interpréteur python
|
||||||
- dans la console créer un objet de type integer, float, string, liste, dictionnaire
|
- dans la console créer un objet de type integer, float, string, liste, dictionnaire
|
||||||
- vérifier les types à l'aide de la fonction `type()`
|
- vérifier les types à l'aide de la fonction
|
||||||
- vérifier que en python tout est objet
|
- vérifier que en python tout est objet
|
||||||
- type de base et types conteneurs
|
- type de base et types conteneurs
|
||||||
- types mutables et types immutables
|
- types mutables et types immutables
|
||||||
|
@ -86,6 +86,8 @@ True
|
||||||
'hu'
|
'hu'
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
>>> s = "ssdfsdf {0} sdfsdfsdf {1}".format("blah", "blih")
|
||||||
|
|
||||||
>>> s= 'a'
|
>>> s= 'a'
|
||||||
>>> dir(s)
|
>>> dir(s)
|
||||||
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
|
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
|
||||||
|
@ -118,11 +120,13 @@ index(), find(), replace()
|
||||||
|
|
||||||
- enlever les accents
|
- enlever les accents
|
||||||
|
|
||||||
|
>>> import unicodedata
|
||||||
>>> s = u"un été même pas chaud"
|
>>> s = u"un été même pas chaud"
|
||||||
>>> import unicodedata as U
|
>>> import unicodedata as U
|
||||||
>>> s2 = ''.join(U.normalize('NFD', x)[0] for x in s)
|
>>> s2 = ''.join(U.normalize('NFD', x)[0] for x in s)
|
||||||
>>> s2
|
>>> s2
|
||||||
u'un ete meme pas chaud'
|
u'un ete meme pas chaud'
|
||||||
|
>>>
|
||||||
|
|
||||||
- enlever la ponctuation
|
- enlever la ponctuation
|
||||||
|
|
||||||
|
@ -132,7 +136,7 @@ u'un ete meme pas chaud'
|
||||||
>>> string.punctuation
|
>>> string.punctuation
|
||||||
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
|
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
|
||||||
|
|
||||||
- l'encodage (unicode et la compression utf-8):
|
- l'encodage (unicode):
|
||||||
|
|
||||||
>>> u = u"éèà bla"
|
>>> u = u"éèà bla"
|
||||||
>>> u
|
>>> u
|
||||||
|
@ -141,6 +145,7 @@ u'\xe9\xe8\xe0 bla'
|
||||||
'\xc3\xa9\xc3\xa8\xc3\xa0 bla'
|
'\xc3\xa9\xc3\xa8\xc3\xa0 bla'
|
||||||
>>> print u.encode("utf-8")
|
>>> print u.encode("utf-8")
|
||||||
éèà bla
|
éèà bla
|
||||||
|
>>>
|
||||||
|
|
||||||
manips importantes de traitement unicode (si on n'est pas en python 3)
|
manips importantes de traitement unicode (si on n'est pas en python 3)
|
||||||
|
|
||||||
|
@ -166,6 +171,7 @@ ordinal not in range(128)
|
||||||
>>> s = u.encode("utf-8")
|
>>> s = u.encode("utf-8")
|
||||||
>>> type(s)
|
>>> type(s)
|
||||||
<type 'str'>
|
<type 'str'>
|
||||||
|
>>>
|
||||||
|
|
||||||
# il faut utiliser .encode(), et pas .decode()...
|
# il faut utiliser .encode(), et pas .decode()...
|
||||||
|
|
||||||
|
@ -193,6 +199,9 @@ ordinal not in range(128)
|
||||||
>>> l
|
>>> l
|
||||||
['e', 'q']
|
['e', 'q']
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. important:: utiliser get plutôt que l'accès par items lorsque l'on n'est pas sûr
|
.. important:: utiliser get plutôt que l'accès par items lorsque l'on n'est pas sûr
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -361,17 +370,14 @@ Ensemble vide :
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
>>> import sets
|
>>> e = set()
|
||||||
>>> e = sets.Set()
|
|
||||||
>>> e
|
>>> e
|
||||||
Set([])
|
Set([])
|
||||||
|
>>> e = set("toto")
|
||||||
>>> import sets
|
|
||||||
>>> e = sets.Set("toto")
|
|
||||||
>>> e
|
>>> e
|
||||||
Set(['t', 'o'])
|
Set(['t', 'o'])
|
||||||
>>> d = {"a":1,"b":2}
|
>>> d = {"a":1,"b":2}
|
||||||
>>> f = sets.Set(d)
|
>>> f = set(d)
|
||||||
>>> f
|
>>> f
|
||||||
Set(['a', 'b'])
|
Set(['a', 'b'])
|
||||||
|
|
||||||
|
@ -391,15 +397,9 @@ Appartenance et définition en extension
|
||||||
b
|
b
|
||||||
t
|
t
|
||||||
o
|
o
|
||||||
</pre>
|
|
||||||
Ajout :
|
|
||||||
<pre class="shell">
|
|
||||||
>>> e.add("a")
|
>>> e.add("a")
|
||||||
>>> e
|
>>> e
|
||||||
Set(['a'])
|
Set(['a'])
|
||||||
>>> e.add("b", "c")
|
|
||||||
Traceback (most recent call last):
|
|
||||||
TypeError: add() takes exactly 2 arguments (3 given)
|
|
||||||
>>> for i in range(5):
|
>>> for i in range(5):
|
||||||
... e.add(i)
|
... e.add(i)
|
||||||
...
|
...
|
||||||
|
@ -414,7 +414,6 @@ Appartenance et définition en extension
|
||||||
...
|
...
|
||||||
>>> e
|
>>> e
|
||||||
# Suppression :
|
# Suppression :
|
||||||
<pre class="shell">
|
|
||||||
>>> f = e.copy()
|
>>> f = e.copy()
|
||||||
>>> f
|
>>> f
|
||||||
Set(['a', 0, 2, 3, 4, 1])
|
Set(['a', 0, 2, 3, 4, 1])
|
||||||
|
@ -482,7 +481,6 @@ Opérations sur les ensembles
|
||||||
|
|
||||||
Opérations ensemblistes
|
Opérations ensemblistes
|
||||||
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
#Pas d'opération "+" :
|
#Pas d'opération "+" :
|
||||||
|
@ -490,14 +488,13 @@ Opérations ensemblistes
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
TypeError: unsupported operand type(s) for +: 'Set' and 'Set'
|
TypeError: unsupported operand type(s) for +: 'Set' and 'Set'
|
||||||
#La réunion :
|
#La réunion :
|
||||||
<pre class="shell">
|
|
||||||
>>> g = e or f
|
>>> g = e or f
|
||||||
>>> g
|
>>> g
|
||||||
Set(['t', 'o'])
|
Set(['t', 'o'])
|
||||||
autre notation :
|
autre notation :
|
||||||
>>> h | e
|
>>> h | e
|
||||||
Set(['a', 'b', 't', 'o'])
|
Set(['a', 'b', 't', 'o'])
|
||||||
>>> h & e
|
>>> h & e
|
||||||
Set(['t', 'o'])
|
Set(['t', 'o'])
|
||||||
>>>
|
>>>
|
||||||
Le complémentaire :
|
Le complémentaire :
|
||||||
|
@ -510,28 +507,7 @@ Opérations ensemblistes
|
||||||
L'intersection, la réunion, le complémentaire :
|
L'intersection, la réunion, le complémentaire :
|
||||||
>>> f
|
>>> f
|
||||||
Set(['a', 2, 3, 4, 1])
|
Set(['a', 2, 3, 4, 1])
|
||||||
>>> f & e
|
>>> f & e
|
||||||
Set(['a', 1, 2, 3, 4])
|
|
||||||
>>> f | e
|
|
||||||
Set(['a', 1, 2, 3, 4, 0])
|
|
||||||
>>> f ^ e
|
|
||||||
Set([0])
|
|
||||||
|
|
||||||
Manipulations diverses
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
>>> ''.join( sets.Set('ciao there!') & sets.Set('hello!') )
|
|
||||||
'!heo'
|
|
||||||
|
|
||||||
Set(['a', 0, 2, 3, 4, 1])
|
|
||||||
>>> f = e.copy()
|
|
||||||
>>> f
|
|
||||||
Set(['a', 0, 2, 3, 4, 1])
|
|
||||||
>>> f.remove(0)
|
|
||||||
>>> f
|
|
||||||
Set(['a', 2, 3, 4, 1])
|
|
||||||
>>> f & e
|
|
||||||
Set(['a', 1, 2, 3, 4])
|
Set(['a', 1, 2, 3, 4])
|
||||||
>>> f | e
|
>>> f | e
|
||||||
Set(['a', 1, 2, 3, 4, 0])
|
Set(['a', 1, 2, 3, 4, 0])
|
||||||
|
@ -592,10 +568,13 @@ compatible, ça marche. Le typage est fort, on demande des types
|
||||||
TypeError: cannot concatenate 'str' and 'int' objects
|
TypeError: cannot concatenate 'str' and 'int' objects
|
||||||
|
|
||||||
>>> addition_forte("1", 4)
|
>>> addition_forte("1", 4)
|
||||||
|
TypeError: cannot concatenate 'str' and 'int' objects
|
||||||
|
|
||||||
|
>>> addition_faible("a", "b")
|
||||||
5
|
5
|
||||||
|
|
||||||
Remarquons que `addition_forte` renvoie forcément un type `int` tandis
|
Remarquons que `addition_faible` renvoie forcément un type `int` tandis
|
||||||
que `addition_faible` peut renvoyer un autre type, ceci est dû au
|
que `addition_forte` peut renvoyer un autre type, ceci est dû au
|
||||||
polymorphisme paramétrique.
|
polymorphisme paramétrique.
|
||||||
|
|
||||||
.. todo:: en python un type et une classe, c'est la même chose
|
.. todo:: en python un type et une classe, c'est la même chose
|
||||||
|
|
Loading…
Reference in New Issue