en and fr python3 courses
This commit is contained in:
94
python/python3/fr/_build/html/_sources/DesignPatterns.txt
Normal file
94
python/python3/fr/_build/html/_sources/DesignPatterns.txt
Normal file
@ -0,0 +1,94 @@
|
||||
Les design patterns
|
||||
=====================
|
||||
|
||||
Les design patterns **ne sont pas** indépendants du langage.
|
||||
Ils dépendent de l'implémentation.
|
||||
|
||||
Le duck typing
|
||||
-------------------
|
||||
|
||||
En python, le duck typing est une forme extreme de programmation par interface.
|
||||
Ne pas hériter dans des directions fausse
|
||||
|
||||
exemple : une voiture ne peut hériter d'un moteur, parce que un moteur n'est pas une voiture.
|
||||
|
||||
hold or wrap ?
|
||||
--------------
|
||||
|
||||
**hold**::
|
||||
|
||||
O.S.method()
|
||||
|
||||
Cela induit un couplage fort (cf la loi de Demeter)
|
||||
|
||||
.. important:: law of Demeter : never more than one dot.
|
||||
|
||||
wrap : a hold by private name, with a::
|
||||
|
||||
self.S.method()
|
||||
|
||||
Ou bien une méthode getattr::
|
||||
|
||||
__getattr__()
|
||||
|
||||
Gets coupling right.
|
||||
|
||||
|
||||
wrapper can restrict, inheritance cannot restrict
|
||||
--------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
class RestrictingWrapper(object):
|
||||
|
||||
def __init__(self, w, block):
|
||||
self._w = w
|
||||
self._block = block
|
||||
|
||||
def __getattr__(self, n):
|
||||
if n in self._block:
|
||||
raise AttributeError, n
|
||||
return getattr(self._w, n)
|
||||
|
||||
Pattern de création : singleton
|
||||
-------------------------------
|
||||
|
||||
# utiliser un module au lieu d'une classe
|
||||
|
||||
in `toto.py`::
|
||||
|
||||
class Toto()
|
||||
toto = Toto()
|
||||
|
||||
in another module::
|
||||
|
||||
from toto import toto
|
||||
|
||||
la factory
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
def load(pkg, obj):
|
||||
m = __import__(pkg, {}, {}, [obj])
|
||||
return getattr(m, obj)
|
||||
|
||||
cls = load('p1.p2.p3', 'c4')
|
||||
|
||||
|
||||
template method (self delegation)
|
||||
---------------------------------
|
||||
|
||||
# Abstract base class::
|
||||
|
||||
def OrganiseMethod()
|
||||
def org_method():
|
||||
def do_this()
|
||||
def do_that()
|
||||
|
||||
def Concrete(OrganiseMethod)
|
||||
def do_this(): ...
|
||||
def do_that(): ...
|
||||
|
||||
il est préférable de lever une NotImplementedError, ce qui revient à faire
|
||||
une classe abstraite.
|
452
python/python3/fr/_build/html/_sources/classes.txt
Normal file
452
python/python3/fr/_build/html/_sources/classes.txt
Normal file
@ -0,0 +1,452 @@
|
||||
Définir et manipuler des classes
|
||||
=================================
|
||||
|
||||
.. glossary::
|
||||
|
||||
objet
|
||||
|
||||
Un object est une entité possédant un type, un état, et un comportement.
|
||||
Un object correspondant généralement à une entité du monde réel, mais
|
||||
cette entité peut être abstraite.
|
||||
On parle aussi d'**instance**.
|
||||
|
||||
**état d'un objet** : ensemble de propriétés auxquelles sont associées des
|
||||
valeurs.
|
||||
|
||||
Les variables de l'objet sont appelées des **attributs**.
|
||||
le comportement d'un :term:`objet` :
|
||||
|
||||
- des actions effectuées sur l'objet
|
||||
- des appels faits sur l'objet
|
||||
|
||||
envois de messages à l'objet = appel de **méthodes**
|
||||
|
||||
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
|
||||
|
||||
|
||||
attribut d'objets et de classes
|
||||
----------------------------------
|
||||
|
||||
>>> o = object()
|
||||
>>> o
|
||||
<object object at 0x7f77c9cda0d0>
|
||||
>>> class C(object): pass
|
||||
...
|
||||
>>> class C: pass
|
||||
...
|
||||
>>> c = C()
|
||||
>>> c.a = 3
|
||||
>>> c.a
|
||||
3
|
||||
>>> vars(c)
|
||||
{'a': 3}
|
||||
>>> c.__dict__
|
||||
{'a': 3}
|
||||
>>> C.__dict__
|
||||
{'__module__': '__main__', '__doc__': None}
|
||||
>>> C.c = 5
|
||||
>>> C.__dict__
|
||||
{'c': 5, '__module__': '__main__', '__doc__': None}
|
||||
>>> c.c
|
||||
5
|
||||
>>> c.z = 3
|
||||
>>> c.z
|
||||
3
|
||||
>>> c.__dict__
|
||||
{'a': 3, 'z': 3}
|
||||
>>> C.__dict__
|
||||
{'c': 5, '__module__': '__main__', '__doc__': None}
|
||||
>>> class MaKlass:
|
||||
... def unefonction(self, x):
|
||||
... print x
|
||||
...
|
||||
>>> MaKlass.__dict__
|
||||
{'__module__': '__main__', '__doc__': None, 'unefonction': <function unefonction at 0x7f77c5b0c488>}
|
||||
>>> k = MaKlass()
|
||||
>>> k.__dict__
|
||||
{}
|
||||
>>> def autrefonc(self, x)
|
||||
File "<stdin>", line 1
|
||||
def autrefonc(self, x)
|
||||
^
|
||||
SyntaxError: invalid syntax
|
||||
>>> def autrefonc(self, x):
|
||||
... print x
|
||||
...
|
||||
>>> k.autrefonc = autrefonc
|
||||
>>> k.__dict__
|
||||
{'autrefonc': <function autrefonc at 0x7f77c5b0c500>}
|
||||
>>> MaKlass.__dict__
|
||||
{'__module__': '__main__', '__doc__': None, 'unefonction': <function unefonction at 0x7f77c5b0c488>}
|
||||
>>> MaKlass.unefonction(k, "toto")
|
||||
toto
|
||||
>>> k.unefonction("toto")
|
||||
toto
|
||||
>>> k.__dict__
|
||||
{'autrefonc': <function autrefonc at 0x7f77c5b0c500>}
|
||||
>>> MaKlass.toto = "test"
|
||||
>>> k.__dict__
|
||||
{'autrefonc': <function autrefonc at 0x7f77c5b0c500>}
|
||||
>>> k.toto
|
||||
'test'
|
||||
>>>
|
||||
|
||||
|
||||
le __dict__ avec l'héritage de classe
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
>>> class A(object): pass
|
||||
...
|
||||
>>> A.__dict__
|
||||
dict_proxy({'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
|
||||
>>> class B(A):
|
||||
... b = 3
|
||||
...
|
||||
>>> class C(B):
|
||||
... c = 2
|
||||
...
|
||||
>>> c = C()
|
||||
>>> o = C()
|
||||
>>> o.__dict__
|
||||
{}
|
||||
>>> o.c
|
||||
2
|
||||
>>> o.b
|
||||
3
|
||||
>>> o.__class__
|
||||
<class '__main__.C'>
|
||||
>>> o.__class__.__dict__
|
||||
dict_proxy({'__module__': '__main__', 'c': 2, '__doc__': None})
|
||||
>>>
|
||||
|
||||
|
||||
method resolution object
|
||||
-----------------------------
|
||||
|
||||
>>> class A(object): pass
|
||||
...
|
||||
>>> A.__mro__
|
||||
(<class '__main__.A'>, <type 'object'>)
|
||||
>>> class B(A): pass
|
||||
...
|
||||
>>> B.__mro__
|
||||
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
|
||||
>>> class C(A, B): pass
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: Error when calling the metaclass bases
|
||||
Cannot create a consistent method resolution
|
||||
order (MRO) for bases A, B
|
||||
>>>
|
||||
|
||||
|
||||
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.
|
||||
|
||||
- interfaces : chaque aspect d'une classe peut être vu comme une interface.
|
||||
|
||||
Une interface décrit un ensemble de comportements.
|
||||
on peut considérer une interface comme un protocole d'utilisation d'un objet
|
||||
dans un contexte donné.
|
||||
|
||||
on peut alors créer des outils qui sauront traiter n'importe quel objet
|
||||
pourvu qu'il respecte une ensemble d'interfaces.
|
||||
|
||||
.. todo:: travailler l'héritage, l'aggrégation, la délégation
|
||||
|
||||
Voici un exemple de classe `Voiture` :
|
||||
|
||||
.. literalinclude:: snippets/heritage.py
|
||||
:pyobject: Voiture
|
||||
|
||||
j'instancie ma classe `Voiture` :
|
||||
|
||||
>>> ma_voiture = Voiture("ma_marque", "150km/h")
|
||||
>>> ma_voiture.roule()
|
||||
'vroummm'
|
||||
>>> ma_voiture.signaletique()
|
||||
'constructeur : ma_marque, vitesse_max 150km/h'
|
||||
|
||||
.. todo:: faire des traitements dans l'init
|
||||
|
||||
- héritage (est une sorte de)
|
||||
- polymorphisme : un objet apparait comme une instance d'une classe parente
|
||||
|
||||
.. literalinclude:: snippets/heritage.py
|
||||
:pyobject: Turbo
|
||||
|
||||
>>> v = DoDoche("marque", 160)
|
||||
>>> v.get_prix()
|
||||
'7000'
|
||||
>>> isinstance(v, Prix)
|
||||
True
|
||||
>>>
|
||||
|
||||
mais l'objet conserve son identité :
|
||||
|
||||
>>> type(v)
|
||||
<type 'Voiture'>
|
||||
|
||||
la fonction ``achete_voiture()`` sera appelée indépendamment du type de l'objet,
|
||||
du moment que l'objet a une méthode `get_prix()`, c'est le duck typing, qu'il
|
||||
est préférable de ramener au polymorphisme d'objet, ou bien utiliser les :mod:`abc`
|
||||
(abstract base classes).
|
||||
|
||||
.. literalinclude:: snippets/heritage.py
|
||||
:pyobject: achete_voiture
|
||||
|
||||
tout le code :
|
||||
|
||||
.. literalinclude:: snippets/heritage.py
|
||||
|
||||
:download:`télécharger le code <snippets/heritage.py>`
|
||||
|
||||
- **l'aggrégation**
|
||||
|
||||
un attribut est lui-même un objet (ce qui est fréquent en python)...
|
||||
|
||||
.. literalinclude:: snippets/aggregation.py
|
||||
|
||||
- **la délégation**
|
||||
|
||||
la fonction "property" est un élément du design de python lui-même
|
||||
|
||||
.. function:: property()
|
||||
|
||||
les patrons de conception
|
||||
---------------------------
|
||||
|
||||
- le patron **factory**
|
||||
|
||||
.. literalinclude:: snippets/patrons.py
|
||||
|
||||
:download:`télécharger usine (factory) <snippets/patrons.py>`
|
||||
|
||||
- le patron **wrapper**
|
||||
|
||||
:download:`télécharger wrapper <snippets/wrap.py>`
|
||||
|
||||
.. literalinclude:: snippets/wrap.py
|
||||
|
||||
exemple d'utilisation de `Wrap()`
|
||||
|
||||
>>> class O:
|
||||
... pass
|
||||
...
|
||||
>>> o = O()
|
||||
>>> o.a = "blah"
|
||||
>>>
|
||||
>>> from wrap import Wrap
|
||||
>>> w = Wrap("monwrap", o)
|
||||
>>> w._name
|
||||
'monwrap'
|
||||
>>> w._w
|
||||
<__main__.O instance at 0x7fbf177aaa28>
|
||||
>>> w._w.a
|
||||
'blah'
|
||||
>>> w.a
|
||||
'blah'
|
||||
>>> w.u
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
File "wrap.py", line 11, in __getattr__
|
||||
return getattr(self._w, name)
|
||||
AttributeError: O instance has no attribute 'u'
|
||||
>>>
|
||||
|
||||
- le patron de conception **itérable**
|
||||
|
||||
:download:`télécharger iterable <snippets/iterable.py>`
|
||||
|
||||
.. literalinclude:: snippets/iterable.py
|
||||
|
||||
- le patron **decorateur**
|
||||
|
||||
:download:`télécharger decorateur <snippets/decorateur.py>`
|
||||
|
||||
.. literalinclude:: snippets/decorateur.py
|
||||
|
||||
>>> def deco(func):
|
||||
... func.attr = 'decorated'
|
||||
... return func
|
||||
...
|
||||
>>> @deco
|
||||
... def f(): pass
|
||||
...
|
||||
>>> f.attr
|
||||
'decorated'
|
||||
>>>
|
||||
|
||||
autre exemple : les méthodes statiques
|
||||
|
||||
>>> class A(object):
|
||||
... @staticmethod
|
||||
... def my_class_method(cls):
|
||||
... # do stuff here
|
||||
|
||||
|
||||
métaclasses
|
||||
-----------------
|
||||
|
||||
>>> class A:
|
||||
... pass
|
||||
...
|
||||
>>> type(A)
|
||||
<type 'classobj'>
|
||||
>>> class B(object): pass
|
||||
...
|
||||
>>> type(B)
|
||||
<type 'type'>
|
||||
>>> help(type)
|
||||
|
||||
>>> C = type('C', (), {})
|
||||
>>> C
|
||||
<class '__main__.C'>
|
||||
>>>
|
||||
|
||||
>>> type(object)
|
||||
<type 'type'>
|
||||
>>> type(type)
|
||||
<type 'type'>
|
||||
>>> isinstance(type, object)
|
||||
True
|
||||
>>> isinstance(object, type)
|
||||
True
|
||||
>>>
|
||||
|
||||
::
|
||||
|
||||
class MaMetaClasse(type):
|
||||
"""Exemple d'une métaclasse."""
|
||||
def __new__(metacls, nom, bases, dict):
|
||||
"""Création de notre classe."""
|
||||
print("On crée la classe {}".format(nom))
|
||||
return type.__new__(metacls, nom, bases, dict)
|
||||
|
||||
class MaClasse(object):
|
||||
__metaclass__ = MaMetaClasse
|
||||
|
||||
|
||||
exemple : forcer l'implémentation d'un singleton avec les métaclasses
|
||||
|
||||
::
|
||||
|
||||
class Singleton(type):
|
||||
instance = None
|
||||
def __call__(cls, *args, **kw):
|
||||
if not cls.instance:
|
||||
cls.instance = super(Singleton, cls).__call__(*args, **kw)
|
||||
return cls.instance
|
||||
|
||||
class ASingleton(object):
|
||||
__metaclass__ = Singleton
|
||||
|
||||
a = ASingleton()
|
||||
b = ASingleton()
|
||||
assert a is b
|
||||
print(a.__class__.__name__, b.__class__.__name__)
|
||||
|
||||
class BSingleton(object):
|
||||
__metaclass__ = Singleton
|
||||
|
||||
c = BSingleton()
|
||||
d = BSingleton()
|
||||
assert c is d
|
||||
print(c.__class__.__name__, d.__class__.__name__)
|
||||
assert c is not a
|
||||
|
52
python/python3/fr/_build/html/_sources/docutils.txt
Normal file
52
python/python3/fr/_build/html/_sources/docutils.txt
Normal file
@ -0,0 +1,52 @@
|
||||
Sphinx et docutils
|
||||
=====================
|
||||
|
||||
Docutils
|
||||
------------
|
||||
|
||||
Il y a des librairies de bas niveau qui permettent de générer de l'odt, je pense à pyUNO, ou bien ezodf_
|
||||
|
||||
.. _ezodf: https://pythonhosted.org/ezodf/
|
||||
|
||||
A l'opposé, il y a des librairies de très haut niveau intégré à des chaînes de documentation avec des sources en xml, des modèles documentaires, des chartes graphiques, etc. Par exemple, scenari_
|
||||
|
||||
.. _scenari: http://scenari-platform.org/projects/scenari/fr/pres/co/
|
||||
|
||||
Un juste milieu est la très intéressante librairie docutils_ :
|
||||
|
||||
.. _docutils: http://docutils.sourceforge.net/
|
||||
|
||||
Il s'agit d'une libairie python très utilisée dans le monde python (par exemple, la documentation officielle python est rédigée en `syntaxe docutils`_).
|
||||
|
||||
.. _`syntaxe docutils` : http://docutils.sourceforge.net/docs/index.html
|
||||
|
||||
C'est une `syntaxe wiki`_ assez puissante, un sur-ensemble de la très connue syntaxe markdown.
|
||||
|
||||
.. _`syntaxe wiki`: http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
||||
|
||||
Pour l'installer::
|
||||
|
||||
apt-get install python-docutils
|
||||
|
||||
Il y a plusieurs utilitaires : ``rst2html``, ``rst2*``, l'utilitaire que je te conseille est : ``rst2odt``.
|
||||
|
||||
Pour l'usage de `rst2odt`_ c'est simple, on part d'un fichier texte formaté en restructured text::
|
||||
|
||||
rst2odt fichier.txt > fichier.odt
|
||||
|
||||
Et voilà simple, pratique, efficace.
|
||||
|
||||
.. _`rst2odt`: http://docutils.sourceforge.net/docs/user/odt.html
|
||||
|
||||
C'est l'outil que nous utilisons en priorité. Voici un exemple d'usage avancé avec l'utilisation d'un modèle::
|
||||
|
||||
rst2odt --create-links --file-insertion-enabled --raw-enabled --endnotes-end-doc \
|
||||
--stylesheet=styles/styles.odt --custom-odt-footer="XXXREMPLACEHEADERXXX" \
|
||||
DossierCommercial.rst > DossierCommercial.odt
|
||||
|
||||
La documentation technique
|
||||
-----------------------------
|
||||
|
||||
L'outil sphinx_
|
||||
|
||||
.. _sphinx: http://sphinx-doc.org/
|
246
python/python3/fr/_build/html/_sources/exceptions.txt
Normal file
246
python/python3/fr/_build/html/_sources/exceptions.txt
Normal file
@ -0,0 +1,246 @@
|
||||
.. default-role:: literal
|
||||
|
||||
Le style de programmation par exceptions
|
||||
========================================
|
||||
|
||||
.. glossary::
|
||||
|
||||
Exception
|
||||
|
||||
Les exceptions permettent de récupérer des situations où le calcul ne peut pas se poursuivre.
|
||||
Dans ces cas, un récupérateur d'exceptions permet de continuer le calcul
|
||||
sachant qu'une des branches a échoué.
|
||||
|
||||
|
||||
Exemple d':term:`exception`
|
||||
|
||||
>>> assert 2 == 1
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
AssertionError
|
||||
|
||||
|
||||
|
||||
La règle du samouraï
|
||||
----------------------
|
||||
|
||||
.. important:: règle du Samouraï : une fonction doit renvoyer le résultat escompté
|
||||
ou bien lever une exception
|
||||
|
||||
|
||||
>>> def function_raise(x):
|
||||
... if not type(x) == int:
|
||||
... raise TypeError("Pas le bon type")
|
||||
... else:
|
||||
... return x + 1
|
||||
...
|
||||
>>> try:
|
||||
... e = function_raise("une string")
|
||||
... except TypeError, e:
|
||||
... print e
|
||||
...
|
||||
Pas le bon type
|
||||
>>
|
||||
|
||||
- la fonction doit renvoyer des valeurs du même type (ou bien ``None``)
|
||||
- la fonction doit lever une exception appropriée
|
||||
|
||||
|
||||
utiliser la pile d'appel pour débugger
|
||||
---------------------------------------
|
||||
|
||||
Utiliser la pile d'appels, elle se lit de bas en haut. Il est possible de
|
||||
provoquer cette pile d'appels.
|
||||
|
||||
::
|
||||
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
.. todo:: s'exercer à lire une pile d'appels un peu complexe.
|
||||
|
||||
|
||||
Traiter une exception avec
|
||||
|
||||
::
|
||||
|
||||
try:
|
||||
...
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
else:
|
||||
bla bla
|
||||
finally:
|
||||
bla bla
|
||||
|
||||
.. attention:: ne **jamais** briser la pile d'appels sans savoir précisément
|
||||
ce que l'on fait, et remonter une autre exception
|
||||
|
||||
Exemple :
|
||||
|
||||
|
||||
>>> def function(x):
|
||||
... if x == 1: raise TypeError("pas le bon type")
|
||||
... else: return "ok"
|
||||
...
|
||||
>>> def function2(x):
|
||||
... try:
|
||||
... return "c'est " + function(x)
|
||||
... except TypeError, e:
|
||||
... raise AssertionError("on a une autre exception là")
|
||||
...
|
||||
>>> try:
|
||||
... function2(1)
|
||||
... except Exception, e:
|
||||
... print e
|
||||
...
|
||||
on a une autre exception là
|
||||
>>>
|
||||
|
||||
Le raise (ou le re-raise) est souvent utilisé pour lever une exception métier
|
||||
et cacher une exception système de bas niveau.
|
||||
|
||||
exemple::
|
||||
|
||||
try:
|
||||
add_s(dn, listdata)
|
||||
except ldap.LDAPError, err:
|
||||
raise MyOwnError(msg + str(err))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
.. todo:: dans quel cas entrons-nous dans le `else` ? dans le `finally` ?
|
||||
|
||||
.. todo:: créer des exceptions métier
|
||||
|
||||
exemple d'exceptions *dans la vraie vie*::
|
||||
|
||||
"user defined exceptions"
|
||||
|
||||
|
||||
# Exceptions for an Option
|
||||
class PropertiesOptionError(AttributeError):
|
||||
"attempt to access to an option with a property that is not allowed"
|
||||
def __init__(self, msg, proptype):
|
||||
self.proptype = proptype
|
||||
super(PropertiesOptionError, self).__init__(msg)
|
||||
|
||||
|
||||
#____________________________________________________________
|
||||
# Exceptions for a Config
|
||||
class ConfigError(Exception):
|
||||
"""attempt to change an option's owner without a value
|
||||
or in case of `_cfgimpl_descr` is None
|
||||
or if a calculation cannot be carried out"""
|
||||
pass
|
||||
|
||||
|
||||
class ContextError(Exception):
|
||||
"""context needed but not given
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ConflictError(Exception):
|
||||
"duplicate options are present in a single config"
|
||||
pass
|
||||
|
||||
|
||||
#____________________________________________________________
|
||||
# miscellaneous exceptions
|
||||
class RequirementError(Exception):
|
||||
"""a recursive loop occurs in the requirements tree
|
||||
requires
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SlaveError(Exception):
|
||||
"problem with a slave's value length"
|
||||
pass
|
||||
|
||||
|
||||
class ConstError(TypeError):
|
||||
"no uniq value in _NameSpace"
|
||||
pass
|
||||
|
||||
Créer le plus possible ses propres exceptions spécifiques au programme
|
||||
La programmation par exception peut vite devenir un style de programmation
|
||||
très utilisé. C'est assez agréable mais le réserver pour la gestion d'une situation
|
||||
particulière, que ça reste une intervention pour les cas non gérés par le programme
|
||||
(en général).
|
||||
|
||||
Les exceptions imbriquées
|
||||
--------------------------------
|
||||
|
||||
>>> try:
|
||||
... ma_func()
|
||||
... except TypeError, e:
|
||||
... do_something()
|
||||
... except Exception, e:
|
||||
... do_somethin_else()
|
||||
...
|
||||
|
||||
Exemple de programme utilisant massivement la programmation par exceptions :
|
||||
`tiramisu`_
|
||||
|
||||
.. _tiramisu: http://tiramisu.labs.libre-entreprise.org/
|
||||
|
||||
|
||||
La hiérarchie des exceptions
|
||||
-----------------------------
|
||||
|
||||
Extrait de la documentation officielle::
|
||||
|
||||
BaseException
|
||||
+-- SystemExit
|
||||
+-- KeyboardInterrupt
|
||||
+-- GeneratorExit
|
||||
+-- Exception
|
||||
+-- StopIteration
|
||||
+-- StandardError
|
||||
| +-- BufferError
|
||||
| +-- ArithmeticError
|
||||
| | +-- FloatingPointError
|
||||
| | +-- OverflowError
|
||||
| | +-- ZeroDivisionError
|
||||
| +-- AssertionError
|
||||
| +-- AttributeError
|
||||
| +-- EnvironmentError
|
||||
| | +-- IOError
|
||||
| | +-- OSError
|
||||
| | +-- WindowsError (Windows)
|
||||
| | +-- VMSError (VMS)
|
||||
| +-- EOFError
|
||||
| +-- ImportError
|
||||
| +-- LookupError
|
||||
| | +-- IndexError
|
||||
| | +-- KeyError
|
||||
| +-- MemoryError
|
||||
| +-- NameError
|
||||
| | +-- UnboundLocalError
|
||||
| +-- ReferenceError
|
||||
| +-- RuntimeError
|
||||
| | +-- NotImplementedError
|
||||
| +-- SyntaxError
|
||||
| | +-- IndentationError
|
||||
| | +-- TabError
|
||||
| +-- SystemError
|
||||
| +-- TypeError
|
||||
| +-- ValueError
|
||||
| +-- UnicodeError
|
||||
| +-- UnicodeDecodeError
|
||||
| +-- UnicodeEncodeError
|
||||
| +-- UnicodeTranslateError
|
||||
+-- Warning
|
||||
+-- DeprecationWarning
|
||||
+-- PendingDeprecationWarning
|
||||
+-- RuntimeWarning
|
||||
+-- SyntaxWarning
|
||||
+-- UserWarning
|
||||
+-- FutureWarning
|
||||
+-- ImportWarning
|
||||
+-- UnicodeWarning
|
||||
+-- BytesWarning
|
20
python/python3/fr/_build/html/_sources/exercices.txt
Normal file
20
python/python3/fr/_build/html/_sources/exercices.txt
Normal file
@ -0,0 +1,20 @@
|
||||
Liste des exercices
|
||||
--------------------
|
||||
|
||||
Voici la liste des liens vers les différents exercices de la formation.
|
||||
|
||||
|
||||
.. todolist::
|
||||
|
||||
|
||||
exercices à faire
|
||||
--------------------
|
||||
|
||||
- implémenter un script qui lit les arguments de la ligne de commande et qui les écrit sur la sortie standard
|
||||
- implémenter les sous-classes de shape point et cercle, calculer le périmètre.
|
||||
- itérer sur une liste et récupérer la valeur maximum de cette liste (la fonction builtin *max*)
|
||||
|
||||
|
||||
>>> a = [3,8,3,5,9,1,4]
|
||||
>>> max(a)
|
||||
9
|
126
python/python3/fr/_build/html/_sources/getting-started.txt
Normal file
126
python/python3/fr/_build/html/_sources/getting-started.txt
Normal file
@ -0,0 +1,126 @@
|
||||
.. default-role :: literal
|
||||
|
||||
Prise en main
|
||||
==============
|
||||
|
||||
L'objectif de ce cours est de vous apprendre à programmer en
|
||||
: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.
|
||||
|
||||
Pour plus d'information : :doc:`docutils`
|
||||
|
||||
Avec python :
|
||||
|
||||
- vous n'avez pas grand chose à savoir pour arriver à faire beaucoup de choses,
|
||||
|
||||
- vous allez pouvoir travailler de manière
|
||||
|
||||
- entièrement autonome
|
||||
- rapide
|
||||
- agile (au sens des méthodes agiles)
|
||||
|
||||
- vous allez progresser rapidement
|
||||
|
||||
- aucune connaissance préalable en programmation n'est requise
|
||||
|
||||
- le hello world en une ligne::
|
||||
|
||||
python -c "print 'hello'"
|
||||
|
||||
- rendre un fichier exécutable et ajouter le she bang::
|
||||
|
||||
#!/usr/bin/env python
|
||||
print "hello"
|
||||
|
||||
.. note:: lorsqu'on lance python sur un programme, des fichiers
|
||||
avec une extension `.pyc` apparaissent.
|
||||
|
||||
.. glossary::
|
||||
|
||||
python
|
||||
|
||||
python_ est un langage de programmation généraliste, libre, totalement
|
||||
orienté objet, dynamiquement typé, semi-interprété ou, pour certaines
|
||||
utilisations optimisées, compilé ou compilé à la volée (JIT).
|
||||
|
||||
sphinx
|
||||
|
||||
sphinx_ est un outil de documentation utilisant la syntaxe wiki
|
||||
docutils_
|
||||
|
||||
- lorsqu'on lance python sans spécifier de nom de fichier, c'est l'interpréteur
|
||||
python qui est lancé (le "prompt")
|
||||
|
||||
|
||||
En python, le dicton le plus répandu est "there must be an obvious way
|
||||
to do it", (il y a certainement une manière évidente de le faire en
|
||||
python), ``import this`` permet de se remémorer les
|
||||
dictons de python. Ce dicton est très différent de l'approche du perl
|
||||
par exemple, qui présuppose : "there is more than one way to do it",
|
||||
c'est-à-dire que en gros en perl, on peut le faire n'importe comment,
|
||||
mais pas en python, enfin en python c'est pas conseillé de le faire à sa
|
||||
sauce, il y a en général une bonne pratique à découvrir et à mettre en place.
|
||||
|
||||
Taper "python" dans votre console
|
||||
|
||||
::
|
||||
|
||||
>>> print "hello world"
|
||||
hello world
|
||||
|
||||
::
|
||||
|
||||
>>> import this
|
||||
|
||||
Beautiful is better than ugly.
|
||||
Explicit is better than implicit.
|
||||
Simple is better than complex.
|
||||
Complex is better than complicated.
|
||||
|
||||
...
|
||||
|
||||
.. seealso::
|
||||
|
||||
les modules, :ref:`namespaces` et la librairie standard
|
||||
:doc:`stdlib`
|
||||
|
||||
pour avoir de l'aide, taper dans le prompt :
|
||||
|
||||
>>> help(function)
|
||||
|
||||
Le bon réflexe de chercher ce qui est le plus répandu et le plus utilisé est le
|
||||
bon en python : on dit que python est livré "batteries included", ce qui
|
||||
signifie que lorsqu'on a un besoin précis il faut chercher dans la librairie
|
||||
standard python, puis dans les librairies les plus utilisées en python, puis en
|
||||
dernier... le reste, ce qui est disponible. Mais si une librairie connue ne
|
||||
fait pas exactement ce qui est attendu et qu'une libraire inconnue du bataillon
|
||||
fait exactement ce qui est attendu, (et a l'air de fonctionner
|
||||
correctement...), alors il faut choisir la libraire inconnue au bataillon.
|
||||
|
||||
|
||||
usage de python
|
||||
------------------
|
||||
|
||||
à 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.
|
||||
|
||||
|
||||
exemple : web server
|
||||
|
||||
pour créer un serveur web simplement::
|
||||
|
||||
python -m server.http 8000 localhost
|
||||
|
||||
exemple : utiliser python pour faire un fichier de conf
|
||||
|
||||
::
|
||||
|
||||
spam = "eggs"
|
||||
actions = [
|
||||
('call_view', 'com.next')
|
||||
]
|
||||
|
||||
|
||||
.. _python: http://www.python.org
|
||||
.. _sphinx: http://sphinx.pocoo.org
|
||||
.. _docutils: http://docutils.sf.net
|
41
python/python3/fr/_build/html/_sources/index.txt
Normal file
41
python/python3/fr/_build/html/_sources/index.txt
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
Apprentissage de la programmation avec python
|
||||
----------------------------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
getting-started
|
||||
settings
|
||||
type
|
||||
structures
|
||||
testsunitaires
|
||||
docutils
|
||||
|
||||
Programmation python, connaissances de base
|
||||
--------------------------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
classes
|
||||
prompt
|
||||
specialmethods
|
||||
exceptions
|
||||
DesignPatterns
|
||||
stdlib
|
||||
|
||||
Récapitulatifs de la formation
|
||||
---------------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
exercices
|
||||
|
||||
Index et recherche
|
||||
-------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
58
python/python3/fr/_build/html/_sources/liens.txt
Normal file
58
python/python3/fr/_build/html/_sources/liens.txt
Normal file
@ -0,0 +1,58 @@
|
||||
Bonjour à toute la promo,
|
||||
|
||||
Comme convenu, voici quelques liens (algorithmiques et autres)
|
||||
|
||||
D'abord, python :)
|
||||
|
||||
https://www.python.org/
|
||||
|
||||
et le tuto dive into python
|
||||
|
||||
http://www.diveintopython3.net/
|
||||
|
||||
et le fameux python challenge
|
||||
|
||||
http://www.pythonchallenge.com/
|
||||
|
||||
c'est un challenge algorithmique qu'on peut résoudre avec du python mais pas forcément, on peut utiliser n'importe quel langage.
|
||||
|
||||
Ceux qui dépasseront la sixième étape (sans regarder les soluces) auront droit à mon respect :)
|
||||
|
||||
Ensuite, la librairie pandas que nous avons vue :
|
||||
|
||||
http://pandas.pydata.org/
|
||||
|
||||
et pandas sur python-simple
|
||||
|
||||
http://www.python-simple.com/python-pandas/stacking-unstacking-dataframe.php
|
||||
|
||||
Sinon après il y a plein de livres, notamment le wikilivre
|
||||
|
||||
https://fr.wikibooks.org/wiki/Programmation_algorithmique/Sommaire
|
||||
|
||||
https://fr.wikibooks.org/wiki/Cat%C3%A9gorie:Programmation_algorithmique_(livre)
|
||||
|
||||
https://fr.wikibooks.org/wiki/Programmation
|
||||
|
||||
après sur wikipédia il y a plein de pages consacrée à divers algorithmes (le voyageur de commerce, les algoritmes tirés de la biologie, etc...) mais on n'a pas vu ça en détails.
|
||||
|
||||
après il y a une bonne présentation des modules et sous-modules (mais c'est de l'ocaml)
|
||||
|
||||
https://www.good-eris.net/formation-ocaml/modules/submod.html
|
||||
|
||||
vous pouvez aussi vous y mettre :
|
||||
|
||||
https://www.good-eris.net/formation-ocaml/intro.html
|
||||
|
||||
un très bon livre pour ocaml
|
||||
|
||||
http://programmer-avec-ocaml.lri.fr/chap10.html
|
||||
|
||||
de très bon livres pour apprendre le python existent aussi, notamment ceux de Tarek Ziadé (un français qui habite en Bourgogne).
|
||||
|
||||
Voilà
|
||||
|
||||
Très bonne continuation à vous tous, à bientôt
|
||||
Gwen
|
||||
|
||||
|
107
python/python3/fr/_build/html/_sources/prompt.txt
Normal file
107
python/python3/fr/_build/html/_sources/prompt.txt
Normal file
@ -0,0 +1,107 @@
|
||||
Interactions avec l'utilisateur
|
||||
===============================
|
||||
|
||||
les prompts
|
||||
--------------
|
||||
|
||||
`raw_input` ou `input`
|
||||
|
||||
(raw_input renvoie une string, input essayes d'évaluer, soyez prudent...)
|
||||
|
||||
>>> from subprocess import call
|
||||
>>> filename = input("quel fichier voulez-vous afficher ?\n")
|
||||
>>> call("cat " + filename, shell=True)
|
||||
|
||||
.. _cmdlabel:
|
||||
|
||||
le module :mod:`cmd` et les interpréteurs
|
||||
--------------------------------------------
|
||||
|
||||
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,
|
||||
c'est-à-dire quelque chose de plus spécifique que **l'application ligne de commande**,
|
||||
ou que l'utilitaire ligne de commande.
|
||||
|
||||
|
||||
Un interpréteur ligne de commande est un programme qui :
|
||||
|
||||
- est forcément plein texte
|
||||
- vous donne un prompt
|
||||
- prends toutes ses entrées d'un coup
|
||||
- produit une sortie (typiquement des lignes de texte)
|
||||
- vous redonne un prompt
|
||||
|
||||
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
|
||||
les entrées d'un coup, et qui vous renvoie une sortie d'un coup.
|
||||
|
||||
le module :mod:`cmd` : exemple d'utilisation
|
||||
|
||||
.. module:: cmd
|
||||
:synopsis: interpréteur ligne de commande
|
||||
|
||||
.. literalinclude:: snippets/cli.py
|
||||
|
||||
:download:`telecharger cmd <snippets/cli.py>`
|
||||
|
||||
::
|
||||
|
||||
>>> from cli import Cli
|
||||
>>> prompt = Cli()
|
||||
>>> prompt.cmdloop()
|
||||
cli (command line interpreter)
|
||||
(type help or ? for commands list)
|
||||
#Prompt> ?
|
||||
|
||||
Documented commands (type help <command>):
|
||||
==========================================
|
||||
EOF exit
|
||||
|
||||
Undocumented commands:
|
||||
======================
|
||||
cmd help quit
|
||||
|
||||
#Prompt>
|
||||
|
||||
pour ajouter une commande, utiliser simplement l'héritage::
|
||||
|
||||
>>> from cli import Cli
|
||||
>>> class Prompt(Cli):
|
||||
... def do_hello(self, line):
|
||||
... print "hello %s", line
|
||||
...
|
||||
>>> prompt = Prompt()
|
||||
>>> prompt.cmdloop()
|
||||
cli (command line interpreter)
|
||||
(type help or ? for commands list)
|
||||
#Prompt> ?
|
||||
|
||||
Documented commands (type help <command>):
|
||||
==========================================
|
||||
EOF exit
|
||||
|
||||
Undocumented commands:
|
||||
======================
|
||||
cmd hello help quit
|
||||
|
||||
#Prompt> hello world
|
||||
|
||||
|
||||
.. todo:: faire un petit projet d'interpréteur ligne de commande du jeu C+/C-
|
||||
|
||||
lire et écrire dans un fichier
|
||||
-------------------------------
|
||||
|
||||
les **handle de fichier** (file handles)
|
||||
|
||||
|
||||
>>>
|
||||
>>> fh = file('test', 'w')
|
||||
>>> fh.write('hello world')
|
||||
>>> fh.close()
|
||||
>>> content = file('test', 'r').read()
|
||||
>>> content
|
||||
'hello world'
|
||||
>>>
|
220
python/python3/fr/_build/html/_sources/settings.txt
Normal file
220
python/python3/fr/_build/html/_sources/settings.txt
Normal file
@ -0,0 +1,220 @@
|
||||
.. default-role:: literal
|
||||
|
||||
Mettre en place son environnement de travail
|
||||
=============================================
|
||||
|
||||
Les éditeurs pour python
|
||||
-----------------------------
|
||||
|
||||
N'importe quel éditeur qui respecte les coding standards du pep8 convient :
|
||||
|
||||
https://www.python.org/dev/peps/pep-0008/
|
||||
|
||||
|
||||
pep8_
|
||||
|
||||
.. _pep8: https://pep8.org/
|
||||
|
||||
|
||||
d'une manière générale, de base un éditeur spartiate peut convenir du moment
|
||||
que l'intentation de 4 espaces est respectée et que les tablulations sont
|
||||
remplacées par des espaces, car le plus important en python c'est l'indentation,
|
||||
et le fait de bien voir ou est le règlage de l'encodage (ça doit être en ``utf-8``)
|
||||
Pour voir si ton éditeur est bien configuré, tu prends n'importe quel fichier python
|
||||
que tu as créé, puis tu faire un ::
|
||||
|
||||
pep8 <mon_fichier.py>
|
||||
|
||||
et `pep` va dire ce qui ne va pas en termes de syntaxe.
|
||||
|
||||
IDLE
|
||||
------
|
||||
|
||||
https://docs.python.org/2/library/idle.html
|
||||
|
||||
Pour information, IDLE est un éditeur intégré (dans la lib standard de python)
|
||||
mais je te le déconseille (trop spartiate).
|
||||
|
||||
un framework de développement intégré : :term:`IDLE`
|
||||
|
||||
.. glossary::
|
||||
|
||||
IDLE
|
||||
IDLE_ est un IDE (environnement de développement intégré) mis à disposition
|
||||
dans la :term:`librairie standard` de python
|
||||
|
||||
.. _IDLE: http://docs.python.org/2/library/idle.html
|
||||
|
||||
|
||||
nano
|
||||
--------
|
||||
|
||||
pour l'exemple, avec **nano**, voici comment faire une config qui permette
|
||||
de coder en python. On configure nano avec le ``.nanorc``
|
||||
|
||||
Exemple de ``.nanorc`` ::
|
||||
|
||||
# replace les tabulations par 4 espaces
|
||||
set tabsize 4
|
||||
set tabstospaces
|
||||
# indente automatiquement
|
||||
set autoindent
|
||||
# la touche home renvoie en debut de code
|
||||
set smarthome
|
||||
# ne met pas de retour chariot a la fin d'une ligne
|
||||
# si elle depasse la largeur du terminal
|
||||
set nowrap
|
||||
unset softwrap
|
||||
|
||||
# chargement de plusieur fichiers
|
||||
set multibuffer
|
||||
|
||||
# coloration syntaxique
|
||||
## Python
|
||||
#include "/usr/share/nano/python.nanorc"
|
||||
|
||||
Gedit
|
||||
---------
|
||||
|
||||
Gedit c'est très bien pour coder en python, mais de base c'est pas sur un serveur,
|
||||
il faut pouvoir être en mode graphique.
|
||||
Il faut règler l'indentation à 4 espaces pour respecter le pep8.
|
||||
Et règler le replacement des tablulations par des espaces.
|
||||
Mais surtout, très vite il faut installer les paquets additionnels, notamment
|
||||
pour que gedit supprime les espaces en fin de ligne par exemple.
|
||||
|
||||
Je l'utilise souvent mais il faut des plugins avec
|
||||
genre ceux-ci (si tu es sur ubuntu)::
|
||||
|
||||
apt-get install gedit-plugins
|
||||
|
||||
dans ce paquet par exemple, l'outil pour commenter-décommenter le code est intéressant
|
||||
(sélection d'un paragraphe, puis Ctrl-M)
|
||||
tu peux régler après la complétion des parenthèses, etc.
|
||||
|
||||
il y a aussi le paquet developer plugins :
|
||||
|
||||
https://apps.ubuntu.com/cat/applications/gedit-developer-plugins/
|
||||
|
||||
Après avec les plugins gedit commence à bien tenir la route.
|
||||
|
||||
Vi
|
||||
----------
|
||||
|
||||
Toujours la même problématiques (espaces, tablulation...)
|
||||
Donc voici une partie de ``.vimrc`` qui le fait::
|
||||
|
||||
"Pour le collage"
|
||||
set pt=<F5>
|
||||
set vb t_vb="
|
||||
set shiftwidth=4
|
||||
set expandtab
|
||||
set ts=4
|
||||
set sw=4
|
||||
syntax on
|
||||
filetype indent on
|
||||
filetype plugin on
|
||||
set autoindent
|
||||
set hlsearch " Surligne les resultats de recherche
|
||||
set wrap " Pas de retour a la ligne auto (affichage)
|
||||
set showmatch " Affiche parenthese correspondante
|
||||
set softtabstop=4 " Largeur d'une tabulation
|
||||
"set fdm=indent " Repli selon l'indentation
|
||||
|
||||
maintenant après il y a un python-mode assez avancé qui permet de faire pas mal de choses.
|
||||
(valider avec la syntaxe avec pylint, valider le pep8...)
|
||||
Mais il faut une config plus avancée.
|
||||
|
||||
|
||||
D'une manière générale, il y a la possibilité de valider avec des outils externes (pylint, pychecker, pep8...) et il y a aussi la possibilité de valider tout ça dans un éditeur.
|
||||
|
||||
|
||||
configurer son éditeur : résumé
|
||||
-----------------------------------
|
||||
|
||||
- les fichiers sources ont l'extension `.py`
|
||||
- une instruction par ligne
|
||||
- les blocs sont marqués par l'indentation (utilser 4 espaces), règler
|
||||
l'éditeur pour transformer les tabulations en espaces
|
||||
|
||||
configurer son prompt python
|
||||
-------------------------------
|
||||
|
||||
.. envvar:: PYTHONPATH
|
||||
|
||||
pointe par défaut sur le répertoire courant, il est possible d'ajouter
|
||||
un path
|
||||
|
||||
à mettre dans votre `.bashrc` :
|
||||
|
||||
::
|
||||
|
||||
export PYTHONPATH:`pwd`
|
||||
|
||||
export PYTHONPATH=$PYTHONPATH:'/usr/share':'/toto/titi/tata'
|
||||
|
||||
alias pyenv='export PYTHONPATH=`pwd`:$PYTHONPATH'
|
||||
|
||||
export PYTHONSTARTUP='/home/gwen/.pystartup'
|
||||
|
||||
.. envvar:: PYTHONSTARTUP
|
||||
|
||||
les trucs à mettre dans vos pytstartups (comme dans vos .bashrc)
|
||||
|
||||
- autocomplétion
|
||||
- affichage de l'historique
|
||||
|
||||
exemple de `.pystartup`
|
||||
|
||||
à télécharger ici : :download:`snippets/pystartup`
|
||||
|
||||
::
|
||||
|
||||
# Store the file in ~/.pystartup, and set an environment variable to point to
|
||||
# it, e.g. "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
|
||||
#
|
||||
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the full
|
||||
# path to your home directory.
|
||||
import rlcompleter
|
||||
import readline
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
import os
|
||||
histfile = os.path.join(os.environ["HOME"], ".pyhist")
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
import atexit
|
||||
atexit.register(readline.write_history_file, histfile)
|
||||
del os, histfile
|
||||
|
||||
# enhanced completion
|
||||
#import rlcompleter2
|
||||
#rlcompleter2.setup()
|
||||
|
||||
|
||||
Consulter la librairie standard
|
||||
-------------------------------------
|
||||
|
||||
.. glossary::
|
||||
|
||||
librairie standard
|
||||
|
||||
Une des règles de base de python est qu'il existe certainement une manière
|
||||
conseillé de faire une tâche en python. Le premier réflexe est d'aller
|
||||
voir dans la `librairie standard`_
|
||||
|
||||
.. _`librairie standard`: http://docs.python.org/2.7/library/index.html
|
||||
|
||||
Premier réflexe : la doc en ligne ou bien installée sur votre disque dur.
|
||||
|
||||
la page d'accueil de la doc officielle python :
|
||||
|
||||
.. image:: images/DocPython.png
|
||||
|
||||
et surtout, une fois la librairie standard abordée, la page d'index des
|
||||
modules :
|
||||
|
||||
.. image:: images/ModuleIndex.png
|
250
python/python3/fr/_build/html/_sources/specialmethods.txt
Normal file
250
python/python3/fr/_build/html/_sources/specialmethods.txt
Normal file
@ -0,0 +1,250 @@
|
||||
Programmation python courante
|
||||
================================
|
||||
|
||||
.. _namespaces:
|
||||
|
||||
les espaces de nommage
|
||||
-----------------------
|
||||
|
||||
L'espace de nommage le plus courant est l'organisation en modules et en packages.
|
||||
|
||||
Packages et modules::
|
||||
|
||||
package/
|
||||
__init__.py
|
||||
module1.py
|
||||
subpackage/
|
||||
__init__.py
|
||||
module2.py
|
||||
|
||||
A utilser pour organiser votre projet
|
||||
Permet de minimiser les risques de conflits de nome
|
||||
Permet de diminuer les entrées dans le :envvar:`PYTHONPATH`
|
||||
|
||||
::
|
||||
|
||||
import package.module1
|
||||
from package.subpackage import module2
|
||||
from package.subpackage.module2 import name
|
||||
|
||||
- le fichier `__init__.py`
|
||||
- `reload(module)` au prompt
|
||||
|
||||
- dangereux : l'import "*", utiliser l'attribut spécial `__all__` pour l'import
|
||||
sélectif
|
||||
|
||||
::
|
||||
|
||||
from os import *
|
||||
|
||||
lance un module en tant que script :
|
||||
|
||||
::
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Organisation modulaire
|
||||
|
||||
- construire des composants élémentaires
|
||||
- combiner ces composants
|
||||
- utiliser une structure pyramidale : les composants sont les éléments de
|
||||
composants plus complexes.
|
||||
|
||||
|
||||
- découplage de l'ensemble en composants indépendants (gros programmes réalisables)
|
||||
- donner de la structure (rendre les gros programmes compréhensibles)
|
||||
- spécifier les liens entre les composants (rendre les programmes maintenables)
|
||||
- identifier les sous-composants indépendants (rendre les programmes réutilisables)
|
||||
- forcer l'abstraction (augmenter la sureté du programme)
|
||||
|
||||
modules chargés et modules importés
|
||||
--------------------------------------
|
||||
|
||||
Les modules susceptibles d'être chargés sont dans le :envvar:`PYTHONPATH`.
|
||||
Mais comment peut-on savoir ou ils sont physiquement (sur le disque dur) ?
|
||||
|
||||
.. envvar:: `sys.modules`
|
||||
|
||||
>>> 'twisted' in sys.modules
|
||||
False
|
||||
>>> import twisted
|
||||
>>> 'twisted' in sys.modules
|
||||
True
|
||||
>>> sys.modules['twisted']
|
||||
<module 'twisted' from '/usr/lib/python2.7/dist-packages/twisted/__init__.pyc'>
|
||||
>>>
|
||||
|
||||
.. attention:: un module présent dans `sys.modules` n'est pas forcément importé
|
||||
dans l'espace de nommage usuel. Il faut importer le module pour
|
||||
pouvoir l'utiliser.
|
||||
|
||||
>>> sys.modules['email']
|
||||
<module 'email' from '/usr/lib/python2.7/email/__init__.pyc'>
|
||||
>>> dir(email)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
NameError: name 'email' is not defined
|
||||
>>>
|
||||
|
||||
Pour récupérer le chemin du module
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(os.path.abspath(<module>.__file__))
|
||||
|
||||
Pour importer un module qui n'est pas dans le `sys.path`
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
fch = open('/path/to/mymodule/custom.py', 'r')
|
||||
my_module = imp.load_module('dhcp_custom', fch, '/path/to/mymodule.py', ('.py', 'U', 1))
|
||||
|
||||
Connaître la version d'un module
|
||||
-------------------------------------
|
||||
|
||||
Exemple : le module ``datetime``
|
||||
|
||||
C'est suivant la version de python car c'est la librairie standard.
|
||||
|
||||
Sinon, en général il y a un attribut __version__
|
||||
|
||||
>>> import sqlalchemy
|
||||
>>> sqlalchemy.__version__
|
||||
'0.9.8'
|
||||
>>>
|
||||
|
||||
|
||||
Les méthodes spéciales
|
||||
-----------------------
|
||||
|
||||
méthodes spéciales correspondants aux interfaces des types de bases :
|
||||
|
||||
.. function:: __init__(self, *args, **kwargs)
|
||||
le constructeur de l'instance d'objet
|
||||
|
||||
.. function:: __add__(self, other)
|
||||
|
||||
correspond à la notation `+`
|
||||
|
||||
exemple :
|
||||
|
||||
.. literalinclude:: snippets/specialmethods.py
|
||||
|
||||
>>> from specialmethods import *
|
||||
>>> z = Zone("titi", 10)
|
||||
>>> z2 = Zone("tutu", 40)
|
||||
>>> z > z2
|
||||
False
|
||||
>>> z + z2
|
||||
<specialmethods.Zone object at 0x7f02d95fb190>
|
||||
>>> z3 = z + z2
|
||||
>>> z3.name
|
||||
'tititutu'
|
||||
>>> z3.level
|
||||
50
|
||||
>>>
|
||||
|
||||
Attributs et accesseurs
|
||||
---------------------------
|
||||
|
||||
python est un langage à attributs, c'est-à-dire que le protocole d'accès
|
||||
aux attributs est règlable.
|
||||
|
||||
>>> class C(object):
|
||||
... classattr = "a class attribute"
|
||||
...
|
||||
>>> cobj = C()
|
||||
>>> cobj.classattr
|
||||
'a class attribute'
|
||||
>>> cobj.insattr = "an instance attribute"
|
||||
>>> cobj.insattr
|
||||
'an instance attribute'
|
||||
>>> C.__dict__['classattr']
|
||||
'a class attribute'
|
||||
>>> cobj.__dict__['insattr']
|
||||
'an instance attribute'
|
||||
|
||||
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::
|
||||
|
||||
__getattr__(self, name)
|
||||
|
||||
__setattr__(self, name, value)
|
||||
|
||||
class AnObject(object):
|
||||
......
|
||||
def __setattr__(self, name, val):
|
||||
if name == 'src': #do something
|
||||
# this will assign the real object.name,
|
||||
#despite __setattr__
|
||||
self.__dict__[name]=val
|
||||
def __getattr__(self, name):
|
||||
# ...
|
||||
try:
|
||||
func = getattr(obj, "method")
|
||||
except AttributeError:
|
||||
... deal with missing method ...
|
||||
else:
|
||||
result = func(args)
|
||||
|
||||
func = getattr(obj, "method", None)
|
||||
if callable(func):
|
||||
func(args)
|
||||
|
||||
- un **attribut** spécial : `__slots__`
|
||||
|
||||
permet de fixer les attributs possibles d'une classe
|
||||
|
||||
::
|
||||
|
||||
>>> class Bar(object):
|
||||
... __slots__ = ("a","b","c")
|
||||
...
|
||||
>>> b = Bar()
|
||||
>>> b.a = "toto"
|
||||
>>> b.a
|
||||
'toto'
|
||||
>>> b.d = "titi"
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
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):
|
||||
... __slots__ = 'x', 'y'
|
||||
...
|
||||
>>> p = Point()
|
||||
>>> p.x = 2
|
||||
>>> p.y = 3
|
||||
>>> p.z = 4
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
AttributeError: 'Point' object has no attribute 'z'
|
||||
>>>
|
||||
|
||||
- notation `|` et notation `>`
|
||||
|
||||
::
|
||||
|
||||
class Test:
|
||||
nombre = 1
|
||||
def __or__(self, other):
|
||||
return self.nombre + other.nombre
|
||||
|
||||
def __lshift__(self, other):
|
||||
self.nombre = self.nombre + other.nombre
|
||||
|
||||
t1 = Test()
|
||||
t2 = Test()
|
||||
t2.nombre = 2
|
||||
print t1 | t2
|
||||
t1 << t2
|
||||
print t1.nombre
|
210
python/python3/fr/_build/html/_sources/stdlib.txt
Normal file
210
python/python3/fr/_build/html/_sources/stdlib.txt
Normal file
@ -0,0 +1,210 @@
|
||||
La :term:`librairie standard`
|
||||
================================
|
||||
|
||||
les builtins
|
||||
-------------
|
||||
|
||||
.. module:: builtins
|
||||
:synopsis: les fonctions directement à disposition sans import spécifique
|
||||
|
||||
- le module :mod:`builtins`, tout ce qui est accessible directement
|
||||
|
||||
>>> dir('__builtins__')
|
||||
['__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']
|
||||
>>>
|
||||
|
||||
- le module :mod:`subprocess`, appels systèmes
|
||||
|
||||
.. module:: subprocess
|
||||
:synopsis: exécuter une commande shell, récupérer le code retour et la sortie
|
||||
|
||||
.. function:: subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)¶
|
||||
|
||||
>>> subprocess.call(["ls", "-l"])
|
||||
0
|
||||
>>> subprocess.call("exit 1", shell=True)
|
||||
1
|
||||
|
||||
.. function:: subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)¶
|
||||
|
||||
>>> subprocess.check_output(["echo", "Hello World!"])
|
||||
'Hello World!\n'
|
||||
|
||||
>>> subprocess.check_output("exit 1", shell=True)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
|
||||
|
||||
- le module :mod:`sys`, paramètres et fonctions systèmes
|
||||
|
||||
.. module:: sys
|
||||
:synopsis: paramètres et fonctions systèmes
|
||||
|
||||
.. envvar:: sys.argv
|
||||
|
||||
la ligne de commande
|
||||
|
||||
.. function:: sys.exit()
|
||||
|
||||
terminer un programme
|
||||
|
||||
.. envvar:: sys.path
|
||||
|
||||
ce qu'il y a dans le :envvar:`PYTHONPATH`
|
||||
|
||||
.. module:: optparse
|
||||
:synopsis: parsing de la ligne de commande
|
||||
|
||||
- le module :mod:`optparse` pour faire des outils ligne de commande
|
||||
|
||||
module plus récent : argparse
|
||||
|
||||
.. literalinclude:: snippets/cmdline.py
|
||||
|
||||
- les modules de tests unitaires :mod:`unittest` et :mod:`doctests`
|
||||
|
||||
.. module:: unittest
|
||||
:synopsis: module de tests unitaires
|
||||
|
||||
.. module:: doctest
|
||||
:synopsis: module de tests unitaires basé sur les docstrings
|
||||
|
||||
- le module :mod:`xml.etree` pour parser du xml
|
||||
|
||||
::
|
||||
|
||||
tree = xml.parse("testFile.xml")
|
||||
rootElement = tree.getroot()
|
||||
bookList = rootElem.findall("Books")
|
||||
if bookList != None:
|
||||
for book in bookList:
|
||||
#faire quelque chose avec les livres
|
||||
|
||||
- le module :mod:`urllib` pour parser les urls et les manipuler (`urllib2`)
|
||||
|
||||
.. module:: urllib
|
||||
:synopsis: parse des urls
|
||||
|
||||
.. function:: urllib.urlopen(url)
|
||||
|
||||
lit une url distante
|
||||
|
||||
.. module:: time
|
||||
:synopsis: caculs de temps
|
||||
|
||||
- :mod:`time` pour la manipulation de temps
|
||||
|
||||
::
|
||||
|
||||
t1 = time.clock()
|
||||
# Do Stuff Here
|
||||
t2 = time.clock()
|
||||
print t2 - t1
|
||||
|
||||
**now**
|
||||
|
||||
::
|
||||
|
||||
import time
|
||||
now = time.localtime(time.time())
|
||||
dateStr = time.strftime("%A, %B %d, %Y, %I:%M %p", now)
|
||||
print dateStr
|
||||
|
||||
.. module:: getpass
|
||||
:synopsis: recupération des mots de passe en ligne de commande
|
||||
|
||||
- le module :mod:`getpass` pour gérer les motes de passe
|
||||
|
||||
>>> import getpass
|
||||
>>> p = getpass.getpass()
|
||||
Password:
|
||||
>>> p
|
||||
'toto'
|
||||
>>>
|
||||
|
||||
|
||||
.. module:: shelve
|
||||
:synopsis: linéarisation de données
|
||||
|
||||
- linéarisation de données
|
||||
|
||||
>>> import shelve
|
||||
>>> shelve.open("database", 'c')
|
||||
{}
|
||||
>>> s = shelve.open("database", 'c')
|
||||
>>> s
|
||||
{}
|
||||
>>> s["o"] = ('a', 'b', 'c')
|
||||
>>> s.cl
|
||||
s.clear s.close
|
||||
>>> s.cl
|
||||
s.clear s.close
|
||||
>>> s.close()
|
||||
>>>
|
||||
|
||||
|
||||
.. module:: abc
|
||||
:synopsis: les abstract base classes
|
||||
|
||||
- le module :mod:`abc` pour faire des interfaces propres
|
||||
|
||||
.. function:: abc.register(subclass)
|
||||
|
||||
exemple
|
||||
|
||||
::
|
||||
|
||||
from abc import ABCMeta
|
||||
|
||||
class MyABC:
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
MyABC.register(tuple)
|
||||
|
||||
assert issubclass(tuple, MyABC)
|
||||
assert isinstance((), MyABC)
|
||||
|
||||
.. module:: hotshot
|
||||
:synopsis: benchmark
|
||||
|
||||
- le module :mod:`hotshot` benchmark
|
||||
|
||||
::
|
||||
|
||||
import hotshot
|
||||
prof = hotshot.Profile('toto.txt')
|
||||
prof.runcall(make_description)
|
||||
prof.close()
|
||||
|
||||
|
||||
- un exemple de librairie externe : :mod:`IPy`
|
||||
|
||||
.. module:: IPy
|
||||
:synopsis: traitement des ips en python < python 3.3 remplacé par ipadress
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install python-ipy
|
||||
|
||||
::
|
||||
|
||||
from IPy import IP
|
||||
|
||||
try:
|
||||
ipy = IP('{0}/{1}'.format(ip, mask), make_net=True)
|
||||
except ValueError:
|
||||
print "marche pas"
|
||||
network = ipy.net()
|
||||
broadcast = ipy.broadcast()
|
||||
return broadcast, network
|
205
python/python3/fr/_build/html/_sources/structures.txt
Normal file
205
python/python3/fr/_build/html/_sources/structures.txt
Normal file
@ -0,0 +1,205 @@
|
||||
.. default-role:: literal
|
||||
|
||||
Structures de contrôle et fonctions
|
||||
====================================
|
||||
|
||||
- tests
|
||||
|
||||
>>> if "a":
|
||||
... print "a"
|
||||
...
|
||||
a
|
||||
>>> if "":
|
||||
... print "hell"
|
||||
...
|
||||
>>> a = 2
|
||||
>>> if a == 1:
|
||||
... print "un"
|
||||
... else:
|
||||
... print "deux"
|
||||
...
|
||||
deux
|
||||
>>>
|
||||
|
||||
.. important:: les types de base ont tous une valeur booléenne
|
||||
|
||||
- itérations
|
||||
|
||||
>>> for i in range(10):
|
||||
... print i
|
||||
...
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
>>>
|
||||
>>> l = range(10)
|
||||
>>> l
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
- tant que
|
||||
|
||||
>>> i = 10
|
||||
>>> while i != 0:
|
||||
... print i
|
||||
... i = i -1
|
||||
...
|
||||
10
|
||||
9
|
||||
8
|
||||
7
|
||||
6
|
||||
5
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
>>>
|
||||
|
||||
fonctions
|
||||
-----------
|
||||
|
||||
>>> def blabla(x):
|
||||
... """fonction qui printe"""
|
||||
... print x
|
||||
...
|
||||
>>>
|
||||
|
||||
il n'y a que des fonctions (et pas de procédures):
|
||||
|
||||
|
||||
>>> def ma_func(x):
|
||||
... "écrit quelque chose dans un fichier"
|
||||
...
|
||||
>>> ma_func("a")
|
||||
>>> print ma_func("a")
|
||||
None
|
||||
>>>
|
||||
|
||||
est équivalent à :
|
||||
|
||||
>>> def ma_func(x):
|
||||
... "écrit quelque chose dans un fichier"
|
||||
... return None
|
||||
|
||||
- arité d'une fonction:
|
||||
|
||||
- paramètre non nommé
|
||||
- paramètre nommé
|
||||
|
||||
>>> def ma_fonction(*args, **kwargs):
|
||||
... print "arguments : ", str(args)
|
||||
... print "argumments nommés", str(kwargs)
|
||||
...
|
||||
>>> ma_fonction("toto", "titi", tutu=2, tata=3)
|
||||
arguments : ('toto', 'titi')
|
||||
argumments nommés {'tata': 3, 'tutu': 2}
|
||||
>>>
|
||||
|
||||
- signature d'une fonction : ça peut renvoyer n'importe quoi (tout ce qu'on veut)
|
||||
|
||||
:term:`return` ou :term:`yield` ?
|
||||
|
||||
.. glossary::
|
||||
|
||||
yield
|
||||
permet de renvoyer le résultat d'une fonction en plusieurs étape
|
||||
à l'aide d'un générateur
|
||||
|
||||
return
|
||||
résultat d'une fonction
|
||||
|
||||
>>> def ma_fonction():
|
||||
... for i in range(10):
|
||||
... yield i
|
||||
...
|
||||
>>> for i in ma_fonction():
|
||||
... print i
|
||||
...
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
>>>
|
||||
|
||||
- espaces de nommage à l'intérieur d'une fonction :
|
||||
|
||||
>>> def toto(x):
|
||||
... print vars()
|
||||
...
|
||||
>>> toto("sdfsdf")
|
||||
{'x': 'sdfsdf'}
|
||||
>>> class A(object):pass
|
||||
...
|
||||
>>> a = A()
|
||||
>>> a.a = "titi"
|
||||
>>> a.b = "toto"
|
||||
>>> vars(a)
|
||||
{'a': 'titi', 'b': 'toto'}
|
||||
|
||||
puisque tout est objet en python, ``vars(mon_objet)`` est équivalent à
|
||||
``mon_objet.__dict__``
|
||||
|
||||
|
||||
- générateurs et compréhension de liste
|
||||
|
||||
les compréhensions de listes permettent de générer de nouvelles listes
|
||||
|
||||
exemple :
|
||||
|
||||
>>> [ 2*i for i in range(10)]
|
||||
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
|
||||
>>>
|
||||
|
||||
>>> [x for x in range(10) if x>5]
|
||||
[6, 7, 8, 9]
|
||||
>>>
|
||||
|
||||
>>> [(i, j) for i in range(2,5) for j in range (4,8)]
|
||||
[(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
|
||||
|
||||
>>> expr = (2*i for i in range(10))
|
||||
>>> expr
|
||||
<generator object <genexpr> at 0x7ff9efa77cd0>
|
||||
>>> for e in expr:
|
||||
... print e
|
||||
...
|
||||
0
|
||||
2
|
||||
4
|
||||
6
|
||||
8
|
||||
10
|
||||
12
|
||||
14
|
||||
16
|
||||
18
|
||||
>>>
|
||||
|
||||
le polymorphisme paramétrique
|
||||
-----------------------------
|
||||
|
||||
polymorphisme exemple de contexte :
|
||||
la fonction print
|
||||
|
||||
>>> print 1
|
||||
1
|
||||
>>> print "1"
|
||||
1
|
||||
|
||||
.. todo:: `print 1` et `print "1"` renvoient le même résultat. Pourquoi ?
|
122
python/python3/fr/_build/html/_sources/testsunitaires.txt
Normal file
122
python/python3/fr/_build/html/_sources/testsunitaires.txt
Normal file
@ -0,0 +1,122 @@
|
||||
Tests unitaires et pile d'appels
|
||||
=================================
|
||||
|
||||
Les tests automatiques sont un complément à la déclaration des types.
|
||||
|
||||
que tester, quoi tester ?
|
||||
|
||||
- que les composants interagissent bien entre eux
|
||||
- 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
|
||||
(systèmes d'exploitation, etc...)
|
||||
|
||||
les types de tests :
|
||||
|
||||
- tests unitaires
|
||||
- tests fonctionnels
|
||||
- tests d'acceptation
|
||||
- tests d'intégration
|
||||
|
||||
Quel outil utiliser ?
|
||||
|
||||
- la :doc:`stdlib` propose le module :mod:`unittest` et unittest2.
|
||||
|
||||
.. module:: py.test
|
||||
:synopsis: outil de test unitaires de la pylib
|
||||
|
||||
- :mod:`py.test` est **le plus simple** (plus simple que unittest)
|
||||
|
||||
http://pytest.org/latest/
|
||||
|
||||
::
|
||||
|
||||
def test_simple():
|
||||
"test si ma_fontion renvoie bien 3"
|
||||
assert ma_fontion(2) == 3
|
||||
|
||||
- `py.test` utilise `assert` et `raises`
|
||||
- `unittest` necessite de faire sytématiquement une classe, puis `assertEqual()`
|
||||
- :mod:`doctest` est plus simple mais charge trop les docstrings
|
||||
|
||||
|
||||
.. todo:: écrire un test unitaire avec `py.test` pour la fonction suivante
|
||||
|
||||
- installer le paquet `python-pytest`
|
||||
|
||||
- écrire un fichier avec une fonction dedans
|
||||
|
||||
::
|
||||
|
||||
def double(x):
|
||||
return x*2
|
||||
|
||||
- écrire un fichier commençant par `test_` qui teste les fonctions du fichier
|
||||
|
||||
options utiles dans `py.test`
|
||||
------------------------------
|
||||
|
||||
::
|
||||
|
||||
py.test --tb=no
|
||||
py.test --tb=short
|
||||
py.test -x (dernière erreur)
|
||||
py.test -s (c'est comme nocapture en fait)
|
||||
py.test -x --nocapture --pdb
|
||||
py.test -xl --pdb
|
||||
|
||||
py.test -k test_simple
|
||||
|
||||
utiliser le module :mod:`pdb`
|
||||
|
||||
.. module:: pdb
|
||||
:synopsis: debugger de la lib standard
|
||||
|
||||
::
|
||||
|
||||
import pdb
|
||||
pdb.set_trace()
|
||||
|
||||
depuis py.test :
|
||||
|
||||
::
|
||||
|
||||
import pytest
|
||||
def test_function():
|
||||
...
|
||||
pytest.set_trace() # invoke PDB debugger and tracing
|
||||
|
||||
|
||||
|
||||
Remarquons que :mod:`pdb` utilise le module :mod:`cmd`, voir :ref:`cmdlabel` qu'on a déjà vu précedemment
|
||||
|
||||
::
|
||||
|
||||
(Pdb) h
|
||||
|
||||
Documented commands (type help <topic>):
|
||||
========================================
|
||||
EOF bt cont enable jump pp run unt
|
||||
a c continue exit l q s until
|
||||
alias cl d h list quit step up
|
||||
args clear debug help n r tbreak w
|
||||
b commands disable ignore next restart u whatis
|
||||
break condition down j p return unalias where
|
||||
|
||||
Miscellaneous help topics:
|
||||
==========================
|
||||
exec pdb
|
||||
|
||||
Undocumented commands:
|
||||
======================
|
||||
retval rv
|
||||
|
||||
(Pdb)
|
||||
|
||||
|
||||
last but not least :
|
||||
|
||||
utiliser pylint ou pychecker
|
||||
|
||||
::
|
||||
|
||||
apt-get install pylint
|
662
python/python3/fr/_build/html/_sources/type.txt
Normal file
662
python/python3/fr/_build/html/_sources/type.txt
Normal file
@ -0,0 +1,662 @@
|
||||
.. default-role:: literal
|
||||
.. default-domain: python
|
||||
|
||||
Typage, types de base
|
||||
======================
|
||||
|
||||
python est un langage dynamiquement typé. qu'est-ce que cela signifie ?
|
||||
|
||||
- pas de déclaration des types (attention différent de l'inférence de types): les variables n'ont pas
|
||||
de type fixé, ce qui signifie que le type est fixé au moment de l'affectation
|
||||
(pendant le rutime).
|
||||
- pas de déclaration des variables (une variable est créée au moyen de la première
|
||||
affectation).
|
||||
|
||||
.. todo:: créer une variable
|
||||
|
||||
>>> a = 3
|
||||
>>> a
|
||||
3
|
||||
|
||||
.. todo::
|
||||
|
||||
- ouvrir l'interpréteur python
|
||||
- dans la console créer un objet de type integer, float, string, liste, dictionnaire
|
||||
- vérifier les types à l'aide de la fonction
|
||||
- vérifier que en python tout est objet
|
||||
- type de base et types conteneurs
|
||||
- types mutables et types immutables
|
||||
|
||||
>>> a = 2
|
||||
>>> b = 3
|
||||
>>> b = 5
|
||||
>>> a
|
||||
2
|
||||
>>> b
|
||||
5
|
||||
|
||||
>>> l = ['a', 'b', 'c', 'd']
|
||||
>>> p = [l, 'e']
|
||||
>>> p
|
||||
[['a', 'b', 'c', 'd'], 'e']
|
||||
>>> l = ['i', 'j']
|
||||
>>> p
|
||||
[['a', 'b', 'c', 'd'], 'e']
|
||||
>>> l
|
||||
['i', 'j']
|
||||
|
||||
.. todo:: jouer avec les types
|
||||
|
||||
- l'interpréteur python comme calculette, les opérations numériques
|
||||
|
||||
>>> x = 1
|
||||
>>> y =2
|
||||
>>> x > y
|
||||
False
|
||||
>>> x == y
|
||||
False
|
||||
>>> x != y
|
||||
True
|
||||
|
||||
- l'interpréteur pour manipuler les strings
|
||||
|
||||
>>> s = "bla bla"
|
||||
'bla bla'
|
||||
>>> s = 'bla bla'
|
||||
'bla bla'
|
||||
>>> s = " 'bli bli' "
|
||||
>>> s
|
||||
" 'bli bli' "
|
||||
>>> s = """ sdfsdf "bla bla" sdfsdf"""
|
||||
>>> s
|
||||
' sdfsdf "bla bla" sdfsdf'
|
||||
>>>
|
||||
>>> s = "bla bla"
|
||||
>>> m = "hu hu"
|
||||
>>> s + m
|
||||
'bla blahu hu'
|
||||
>>> m * 3
|
||||
'hu huhu huhu hu'
|
||||
>>>
|
||||
>>> len(m)
|
||||
5
|
||||
>>>
|
||||
>>> m[3]
|
||||
'h'
|
||||
>>> m[3:5]
|
||||
'hu'
|
||||
>>>
|
||||
|
||||
>>> s = "ssdfsdf {0} sdfsdfsdf {1}".format("blah", "blih")
|
||||
|
||||
>>> s= 'a'
|
||||
>>> 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']
|
||||
>>> t = "abc"
|
||||
>>> t.startswith("a")
|
||||
True
|
||||
>>> l = ['a', 'b', 'c']
|
||||
>>> "-".join(l)
|
||||
'a-b-c'
|
||||
>>>
|
||||
|
||||
.. todo:: lower(), upper(), strip(), title()
|
||||
|
||||
.. todo: recherche et remplacement dans une string
|
||||
|
||||
index(), find(), replace()
|
||||
|
||||
- le module :mod:`regexp`
|
||||
|
||||
.. module:: regexp
|
||||
:synopsis: expression régulières
|
||||
|
||||
>>> import re
|
||||
>>> s = "sdf dfdfdf blah bla df"
|
||||
>>> re.findall(r'\w*', s)
|
||||
['sdf', '', 'dfdfdf', '', 'blah', '', 'bla', '', 'df', '']
|
||||
>>> re.findall(r'df*', s)
|
||||
['df', 'df', 'df', 'df', 'df']
|
||||
>>>
|
||||
|
||||
unicode
|
||||
------------
|
||||
|
||||
En python 2.X : deux types : `str` et `unicode` (en python 3 ces types sont unifiés)
|
||||
|
||||
on peut facilement tomber sur des erreurs unicode::
|
||||
|
||||
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0:
|
||||
ordinal not in range(128)
|
||||
|
||||
|
||||
- l'encodage (unicode):
|
||||
|
||||
on part d'un objet unicode :
|
||||
|
||||
>>> u = u"éèà bla"
|
||||
>>> u
|
||||
u'\xe9\xe8\xe0 bla'
|
||||
|
||||
on le transforme en string utf-8 :
|
||||
|
||||
>>> u.encode("utf-8")
|
||||
'\xc3\xa9\xc3\xa8\xc3\xa0 bla'
|
||||
>>> print u.encode("utf-8")
|
||||
éèà bla
|
||||
>>>
|
||||
|
||||
on peut partir d'une string en utf-8, puis::
|
||||
|
||||
|
||||
|
||||
manips importantes de traitement unicode (si on n'est pas en python 3)
|
||||
|
||||
>>> u = u"ésdsfè"
|
||||
>>> u
|
||||
u'\xe9sdsf\xe8'
|
||||
>>> print u
|
||||
ésdsfè
|
||||
>>> str(u)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0:
|
||||
ordinal not in range(128)
|
||||
>>> u.encode("utf-8")
|
||||
'\xc3\xa9sdsf\xc3\xa8'
|
||||
>>> s = u.encode("utf-8")
|
||||
>>> type(s)
|
||||
<type 'str'>
|
||||
>>>
|
||||
|
||||
Il faut utiliser ``.encode()``, et pas ``.decode()``::
|
||||
|
||||
if type(s) == unicode #types.UnicodeType:
|
||||
bla bla
|
||||
|
||||
if type(s) == str:
|
||||
rien à faire
|
||||
|
||||
manipulations diverses :
|
||||
|
||||
- enlever les accents
|
||||
|
||||
>>> import unicodedata
|
||||
>>> s = u"un été même pas chaud"
|
||||
>>> import unicodedata as U
|
||||
>>> s2 = ''.join(U.normalize('NFD', x)[0] for x in s)
|
||||
>>> s2
|
||||
u'un ete meme pas chaud'
|
||||
>>>
|
||||
|
||||
- enlever la ponctuation
|
||||
|
||||
>>> import re
|
||||
>>> import string
|
||||
>>> rgx = re.compile('[%s]' % string.punctuation)
|
||||
>>> string.punctuation
|
||||
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
|
||||
|
||||
|
||||
|
||||
tuples, listes, dictionnaires
|
||||
---------------------------------
|
||||
|
||||
|
||||
>>> t = (1,2,3)
|
||||
>>> l = [1,2,3]
|
||||
>>> d = {'a': 2, 'b':3, 'c':4}
|
||||
>>>
|
||||
>>> l = ['e','p','q','t']
|
||||
>>> l.pop()
|
||||
't'
|
||||
>>> l
|
||||
['e', 'p', 'q']
|
||||
>>> l
|
||||
['e', 'p', 'q']
|
||||
>>> l.pop(1)
|
||||
'p'
|
||||
>>> l
|
||||
['e', 'q']
|
||||
>>>
|
||||
exercice
|
||||
-------------
|
||||
|
||||
écrire la string "1-2-3-4-5-6-7-8-9" programmatiquement
|
||||
|
||||
>>> [str(i) for i in l]
|
||||
['1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
>>> l2 = []
|
||||
>>> for i in l:
|
||||
... l2.append(str(i))
|
||||
...
|
||||
>>> l2
|
||||
['1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
>>>
|
||||
>>> l = range(1,9)
|
||||
>>> l2 = [str(i) for i in l]
|
||||
>>> "-".join(l2)
|
||||
'1-2-3-4-5-6-7-8'
|
||||
>>> s= "-"
|
||||
>>> l2.extend(range(20))
|
||||
>>> l2
|
||||
['1', '2', 'sdfsdf', '3', '4', '5', '6', '7', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
|
||||
>>> l + l2
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, '1', '2', 'sdfsdf', '3', '4', '5', '6', '7', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
|
||||
>>> l.extend(l2)
|
||||
KeyboardInterrupt
|
||||
>>> l = []
|
||||
>>> l = list()
|
||||
>>> list
|
||||
<type 'list'>
|
||||
>>> list()
|
||||
[]
|
||||
>>> list(range(2))
|
||||
[0, 1]
|
||||
>>> tuple
|
||||
<type 'tuple'>
|
||||
>>> t = (1,2,3)
|
||||
>>> t
|
||||
(1, 2, 3)
|
||||
>>> list(t)
|
||||
[1, 2, 3]
|
||||
>>> t
|
||||
(1, 2, 3)
|
||||
>>> type(t)
|
||||
<type 'tuple'>
|
||||
>>>
|
||||
|
||||
|
||||
.. important:: utiliser get plutôt que l'accès par items lorsque l'on n'est pas sûr
|
||||
|
||||
::
|
||||
|
||||
>>> d = {}
|
||||
>>> d.get('toto')
|
||||
>>> d['toto'] ='titi'
|
||||
>>> d.get('toto')
|
||||
'titi'
|
||||
>>> print d.get('toto')
|
||||
titi
|
||||
>>> print d.get('to')
|
||||
None
|
||||
>>> d['tot']
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
KeyError: 'tot'
|
||||
>>>
|
||||
KeyboardInterrupt
|
||||
>>>
|
||||
|
||||
>>> x=dict(a=23,b=45,c=67,d=89)
|
||||
>>> x
|
||||
{'a': 23, 'c': 67, 'b': 45, 'd': 89}
|
||||
>>> y=dict.fromkeys(range(4), 'ho')
|
||||
>>> y
|
||||
{0: 'ho', 1: 'ho', 2: 'ho', 3: 'ho'}
|
||||
|
||||
# and a new method to fetch-and-remove an item, by key:
|
||||
|
||||
>>> x.pop('c')
|
||||
67
|
||||
>>> x
|
||||
{'a': 23, 'b': 45, 'd': 89}
|
||||
>>> x.pop('z')
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
KeyError: 'z'
|
||||
>>> x.pop('z', 55)
|
||||
55
|
||||
|
||||
>>> for x in enumerate('ciao'): print x
|
||||
...
|
||||
(0, 'c')
|
||||
(1, 'i')
|
||||
(2, 'a')
|
||||
(3, 'o')
|
||||
>>>
|
||||
|
||||
|
||||
.. module:: collections
|
||||
:synopsis: autres types de données
|
||||
|
||||
- le module :mod:`collections` :
|
||||
|
||||
- `OrderedDict`, `defaultdict`
|
||||
|
||||
remarques sur les tuples
|
||||
|
||||
>>> 1,
|
||||
(1,)
|
||||
>>> (1,)
|
||||
(1,)
|
||||
>>> (1)
|
||||
1
|
||||
>>> ()
|
||||
()
|
||||
>>> tuple()
|
||||
()
|
||||
>>> value = 1,
|
||||
>>> value
|
||||
(1,)
|
||||
|
||||
.. todo:: addition de listes, append, tranches, tri de listes
|
||||
|
||||
::
|
||||
|
||||
def remove_duplicates(lst):
|
||||
...
|
||||
|
||||
l = [4, 7, 30, "hello", 7, "world", 30, 7]
|
||||
remove_duplicates(l)
|
||||
assert l == [4, 7, 30, "hello", "world"]
|
||||
|
||||
.. todo:: defaultdict, get (avec une valeur par défaut)
|
||||
|
||||
- tri de liste personnalisé :
|
||||
|
||||
.. literalinclude:: snippets/sorter.py
|
||||
|
||||
>>> 'a' in d
|
||||
True
|
||||
>>> t[1]
|
||||
2
|
||||
>>>
|
||||
>>> for i in l:
|
||||
... print i
|
||||
...
|
||||
1
|
||||
2
|
||||
3
|
||||
>>>
|
||||
>>> for i in d:
|
||||
... print i
|
||||
...
|
||||
a
|
||||
c
|
||||
b
|
||||
>>>
|
||||
>>> for key, value in d.items():
|
||||
... print key, " : ", value
|
||||
...
|
||||
a : 2
|
||||
c : 4
|
||||
b : 3
|
||||
>>>
|
||||
|
||||
.. todo:: l'interpréteur python pour l'introspection des objets
|
||||
|
||||
en python, **pas besoin de déclaration de type**. Qu'est-ce que ça veut dire ?
|
||||
|
||||
>>> type(1)
|
||||
<type 'int'>
|
||||
>>>
|
||||
>>> dir(3)
|
||||
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
|
||||
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__',
|
||||
'__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__',
|
||||
'__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__',
|
||||
'__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__',
|
||||
'__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__',
|
||||
'__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__',
|
||||
'__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__',
|
||||
'__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
|
||||
'__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
|
||||
'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
|
||||
>>>
|
||||
>>> type(3)
|
||||
<type 'int'>
|
||||
>>>
|
||||
|
||||
- Le type set
|
||||
|
||||
Set
|
||||
|
||||
collection non ordonnées d'éléments uniques
|
||||
|
||||
|
||||
- le type set immutable et le type set mutable.
|
||||
- un ensemble peut être étendu ou bien seulement englobé
|
||||
|
||||
::
|
||||
|
||||
Manipulations non supportées
|
||||
|
||||
>>> e["a"]
|
||||
Traceback (most recent call last):
|
||||
TypeError: unsubscriptable object
|
||||
>>> e.append("a")
|
||||
Traceback (most recent call last):
|
||||
AttributeError: 'Set' object has no attribute 'append'
|
||||
|
||||
Création
|
||||
|
||||
Ensemble vide :
|
||||
|
||||
::
|
||||
|
||||
>>> e = set()
|
||||
>>> e
|
||||
Set([])
|
||||
>>> e = set("toto")
|
||||
>>> e
|
||||
Set(['t', 'o'])
|
||||
>>> d = {"a":1,"b":2}
|
||||
>>> f = set(d)
|
||||
>>> f
|
||||
Set(['a', 'b'])
|
||||
|
||||
Appartenance et définition en extension
|
||||
|
||||
::
|
||||
|
||||
Set(['a', 'b'])
|
||||
>>> "a" in i
|
||||
True
|
||||
>>> len(h)
|
||||
4
|
||||
>>> for u in h:
|
||||
... print u
|
||||
...
|
||||
a
|
||||
b
|
||||
t
|
||||
o
|
||||
>>> e.add("a")
|
||||
>>> e
|
||||
Set(['a'])
|
||||
>>> for i in range(5):
|
||||
... e.add(i)
|
||||
...
|
||||
>>> e
|
||||
Set(['a', 0, 2, 3, 4, 1])
|
||||
Set(['a'])
|
||||
>>> e.add("b", "c")
|
||||
Traceback (most recent call last):
|
||||
TypeError: add() takes exactly 2 arguments (3 given)
|
||||
>>> for i in range(5):
|
||||
... e.add(i)
|
||||
...
|
||||
>>> e
|
||||
# Suppression :
|
||||
>>> f = e.copy()
|
||||
>>> f
|
||||
Set(['a', 0, 2, 3, 4, 1])
|
||||
>>> f.remove(0)
|
||||
|
||||
Opérations sur les ensembles
|
||||
|
||||
::
|
||||
|
||||
>>> v = sets.Set()
|
||||
|
||||
>>> e.issubset(f)
|
||||
False
|
||||
>>> f.issubset(e)
|
||||
True
|
||||
>>> e.issuperset(f)
|
||||
True
|
||||
>>> f < e
|
||||
True
|
||||
>>> f > e
|
||||
False
|
||||
>>> e
|
||||
Set(['a', 0, 2, 3, 4, 1, ImmutableSet(['p'])])
|
||||
>>> e.copy()
|
||||
Set(['a', 0, 2, 3, 4, 1, ImmutableSet(['p'])])
|
||||
>>> e.remove(3)
|
||||
>>> e
|
||||
Set(['a', 0, 2, 4, 1, ImmutableSet(['p'])])
|
||||
>>> 0 in e
|
||||
True
|
||||
>>> e.pop()
|
||||
'a'
|
||||
>>> e
|
||||
Set([0, 2, 4, 1, ImmutableSet(['p'])])
|
||||
>>> e.pop()
|
||||
0
|
||||
>>> e.discard(4)
|
||||
>>> e
|
||||
Set([2, 1, ImmutableSet(['p'])])
|
||||
>>> e.discard("p")
|
||||
>>> e
|
||||
Set([2, 1, ImmutableSet(['p'])])
|
||||
>>> e.discard(sets.Set("p"))
|
||||
>>> e
|
||||
Set([2, 1])
|
||||
>>>
|
||||
>>> e -= f
|
||||
>>> e
|
||||
Set([])
|
||||
>>> f
|
||||
Set(['a', 2, 3, 4, 1])
|
||||
>>>
|
||||
>>> e.clear()
|
||||
>>> e
|
||||
Set([])
|
||||
>>>
|
||||
# copy
|
||||
>>> h == e
|
||||
False
|
||||
>>> h != e
|
||||
True
|
||||
>>> u = h.copy()
|
||||
>>> u
|
||||
Set(['a', 'b', 't', 'o'])
|
||||
|
||||
Opérations ensemblistes
|
||||
|
||||
::
|
||||
|
||||
#Pas d'opération "+" :
|
||||
>>> h = e + f
|
||||
Traceback (most recent call last):
|
||||
TypeError: unsupported operand type(s) for +: 'Set' and 'Set'
|
||||
#La réunion :
|
||||
>>> g = e or f
|
||||
>>> g
|
||||
Set(['t', 'o'])
|
||||
autre notation :
|
||||
>>> h | e
|
||||
Set(['a', 'b', 't', 'o'])
|
||||
>>> h & e
|
||||
Set(['t', 'o'])
|
||||
>>>
|
||||
Le complémentaire :
|
||||
>>> h = e ^ f
|
||||
>>> h
|
||||
Set(['a', 'b', 't', 'o'])
|
||||
La différence :
|
||||
>>> i = h - e
|
||||
>>> i
|
||||
L'intersection, la réunion, le complémentaire :
|
||||
>>> f
|
||||
Set(['a', 2, 3, 4, 1])
|
||||
>>> f & e
|
||||
Set(['a', 1, 2, 3, 4])
|
||||
>>> f | e
|
||||
Set(['a', 1, 2, 3, 4, 0])
|
||||
>>> f ^ e
|
||||
Set([0])
|
||||
|
||||
différence entre type et isinstance
|
||||
------------------------------------
|
||||
|
||||
`type()` ne gère pas l'héritage alors que `isinstance()` si:
|
||||
|
||||
>>> class MyClass(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
>>> a = MyClass()
|
||||
>>> type(a) == MyClass
|
||||
True
|
||||
>>> type(a) == object
|
||||
False
|
||||
>>> isinstance(a, MyClass)
|
||||
True
|
||||
>>> isinstance(a, object)
|
||||
True
|
||||
>>>
|
||||
|
||||
Dans la **PEP 8**, Guido demande explicitement d'utiliser isinstance et non type
|
||||
|
||||
.. note::
|
||||
|
||||
citation :
|
||||
|
||||
Object type comparisons should always use isinstance() instead
|
||||
of comparing types directly.
|
||||
|
||||
Yes: if isinstance(obj, int):
|
||||
|
||||
No: if type(obj) is int:
|
||||
|
||||
|
||||
inférence de type
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. todo:: coercion, typage dynamique, inférence de type
|
||||
|
||||
exemple::
|
||||
|
||||
def addition_forte(x, y):
|
||||
return int(x) + int(y)
|
||||
|
||||
def addition_faible(x, y):
|
||||
return x + y
|
||||
|
||||
dans `addition_faible`, il n'y a pas de casting de type, on n'essaye pas
|
||||
de transformer ça en un type donné, c'est-à-dire que si `x` et `y` sont
|
||||
compatible, ça marche. Le typage est fort, on demande des types
|
||||
|
||||
>>> addition_faible("1", 4)
|
||||
TypeError: cannot concatenate 'str' and 'int' objects
|
||||
|
||||
>>> addition_forte("1", 4)
|
||||
TypeError: cannot concatenate 'str' and 'int' objects
|
||||
|
||||
>>> addition_faible("a", "b")
|
||||
5
|
||||
|
||||
Remarquons que `addition_faible` renvoie forcément un type `int` tandis
|
||||
que `addition_forte` peut renvoyer un autre type, ceci est dû au
|
||||
polymorphisme paramétrique.
|
||||
|
||||
.. todo:: en python un type et une classe, c'est la même chose
|
||||
|
||||
.. todo:: "duck typing" en python
|
||||
|
||||
- le typage
|
||||
|
||||
- typage fort
|
||||
|
||||
- statique : déclaration ou bien inférence (déduction) lisible dans le source
|
||||
(exemple : java)
|
||||
|
||||
- typage dynamique : une variable est typée en fonction de son contenu
|
||||
|
||||
- typage faible :
|
||||
|
||||
- une donnée n'aura pas spécialement de type : les nombres, les chaînes de
|
||||
caractères, les booléens, etc. seront tous des scalaires et ne seront
|
||||
différenciés que par leur valeur et par le contexte de leur utilisation
|
Reference in New Issue
Block a user