modèle objet de python
This commit is contained in:
parent
2ddd3e2c18
commit
1645146d0d
|
@ -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.
|
|
@ -1,61 +0,0 @@
|
|||
# coding: utf-8
|
||||
minuscules = 'abcdefghijklmnopqrstuvwxyz'
|
||||
majuscules = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
def rotation(chaine, x):
|
||||
"""
|
||||
Effectue une rotation de x caractères vers la droite:
|
||||
>>> rotation('abcde', 2)
|
||||
'cdeab'
|
||||
"""
|
||||
return chaine[x:] + chaine[:x]
|
||||
|
||||
def index(c, chaine):
|
||||
"""
|
||||
Trouve l'index de c dans la chaine:
|
||||
>>> index('n', 'bonjour')
|
||||
2
|
||||
"""
|
||||
for i in range(len(chaine)):
|
||||
if (c == chaine[i]):
|
||||
return i
|
||||
return -1
|
||||
|
||||
def chiffre_minuscules(chaine, x):
|
||||
"""
|
||||
Chiffre une chaîne composée de minuscules
|
||||
>>> chiffre_minuscules('bonjour', 3)
|
||||
'erqmrxu'
|
||||
"""
|
||||
r = rotation(minuscules, x)
|
||||
resultat = ''
|
||||
for lettre in chaine:
|
||||
resultat = resultat + r[index(lettre, minuscules)]
|
||||
return resultat
|
||||
|
||||
def chiffre(chaine, x):
|
||||
"""
|
||||
Chiffre une chaîne quelconque
|
||||
>>> chiffre('Bonjour les amis!', 3)
|
||||
'Erqmrxu ohv dplv!'
|
||||
"""
|
||||
r_min = rotation(minuscules, x)
|
||||
r_maj = rotation(majuscules, x)
|
||||
resultat = ''
|
||||
for lettre in chaine:
|
||||
if lettre in minuscules:
|
||||
resultat = resultat + r_min[index(lettre, minuscules)]
|
||||
elif lettre in majuscules:
|
||||
resultat = resultat + r_maj[index(lettre, majuscules)]
|
||||
else:
|
||||
resultat = resultat + lettre
|
||||
return resultat
|
||||
|
||||
#############################################################################
|
||||
# Programme principal
|
||||
#############################################################################
|
||||
print(chiffre_minuscules('bonjour', 3))
|
||||
print(chiffre('Bonjour les amis!', 3))
|
||||
print(chiffre('Erqmrxu ohv dplv!', 23))
|
||||
print(chiffre('Eudyr, yrxv dyhc ilql fhw hahuflfh!', 23))
|
||||
|
|
@ -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
|
||||
|
|
@ -29,7 +29,7 @@ import os
|
|||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.pngmath', 'sphinx.ext.ifconfig',
|
||||
'sphinx.ext.pngmath', 'sphinx.ext.ifconfig', 'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
# ajout des cours avec solution des exercices ou non
|
||||
|
@ -40,6 +40,7 @@ def setup(app):
|
|||
exercice = False
|
||||
correction = False
|
||||
|
||||
todo_include_todos = True
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
|
|
|
@ -6,8 +6,12 @@ Introduction à l'algorithmique
|
|||
|
||||
presentation
|
||||
fondement
|
||||
mechanism
|
||||
prompt
|
||||
langage
|
||||
programme
|
||||
modularite
|
||||
modules
|
||||
classes
|
||||
DesignPatterns
|
||||
annexes/index
|
||||
|
|
|
@ -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'
|
||||
>>>
|
|
@ -0,0 +1,8 @@
|
|||
class A:
|
||||
pass
|
||||
|
||||
class B:
|
||||
pass
|
||||
|
||||
a = A()
|
||||
a.b = B()
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf8 -*-
|
||||
"""Command line interpreter
|
||||
"""
|
||||
import cmd
|
||||
|
||||
# ____________________________________________________________
|
||||
# this Cli is a model of a basic use of a simple cmd
|
||||
class Cli(cmd.Cmd):
|
||||
def __init__(self):
|
||||
cmd.Cmd.__init__(self)
|
||||
self.doc_header = "Documented commands (type help <command>):"
|
||||
self.undoc_header = "Undocumented commands"
|
||||
self.prompt = "#Prompt> "
|
||||
self.intro = """cli (command line interpreter)
|
||||
(type help or ? for commands list)"""
|
||||
self.ruler = "-"
|
||||
|
||||
def emptyline(self):
|
||||
print "Type 'exit' to finish withe the session or type ? for help."
|
||||
|
||||
def default(self, line):
|
||||
print "unknown command prefix"
|
||||
print "*** unknown syntax : %s (type 'help' for help for a list of valid commands)"%line
|
||||
self.emptyline()
|
||||
|
||||
def do_exit(self, line):
|
||||
"""Exits from the console"""
|
||||
return True
|
||||
|
||||
def do_quit(self, line):
|
||||
return True
|
||||
|
||||
def do_EOF(self, args):
|
||||
"""Exit on system end of file character"""
|
||||
return True
|
||||
|
||||
# ____________________________________________________________
|
||||
# commands pre and post actions
|
||||
# def precmd(self, line):
|
||||
# return line
|
||||
# def postcmd(self, stop, line):
|
||||
# # if there is a problem, just return True : it stops everythings
|
||||
# stop = True
|
||||
# return stop # quit if stop == True
|
||||
# ____________________________________________________________
|
||||
# program pre and post actions
|
||||
# def preloop(self):
|
||||
# # action for the beginning of the program
|
||||
# pass
|
||||
|
||||
# def postloop(self):
|
||||
# # action for the end of the program
|
||||
# print "exit cli"
|
||||
# ____________________________________________________________
|
||||
|
||||
class HelloCli(Cli):
|
||||
|
||||
def input_hello(self, line):
|
||||
return line.replace(",", " and ")
|
||||
|
||||
def output_hello(self, result):
|
||||
print result
|
||||
|
||||
def do_hello(self, line):
|
||||
self.output_hello("hello, " + self.input_hello(line))
|
||||
#return False # if you want to stay into the cli
|
||||
return True # if you want to exit
|
||||
|
||||
if __name__ == '__main__':
|
||||
prompt = HelloCli()
|
||||
prompt.cmdloop("intro, modifies Cmd.intro")
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Module docstring.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import optparse
|
||||
|
||||
def process_command_line(argv):
|
||||
"""
|
||||
Return a 2-tuple: (settings object, args list).
|
||||
`argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
|
||||
"""
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
# initialize the parser object:
|
||||
parser = optparse.OptionParser(
|
||||
formatter=optparse.TitledHelpFormatter(width=78),
|
||||
add_help_option=None)
|
||||
|
||||
# define options here:
|
||||
parser.add_option( # customized description; put --help last
|
||||
'-h', '--help', action='help',
|
||||
help='Show this help message and exit.')
|
||||
|
||||
settings, args = parser.parse_args(argv)
|
||||
|
||||
# check number of arguments, verify values, etc.:
|
||||
if args:
|
||||
parser.error('program takes no command-line arguments; '
|
||||
'"%s" ignored.' % (args,))
|
||||
|
||||
# further process settings & args if necessary
|
||||
|
||||
return settings, args
|
||||
|
||||
def main(argv=None):
|
||||
settings, args = process_command_line(argv)
|
||||
# application code here, like:
|
||||
# run(settings, args)
|
||||
return 0 # success
|
||||
|
||||
if __name__ == '__main__':
|
||||
status = main()
|
||||
sys.exit(status)
|
|
@ -0,0 +1,10 @@
|
|||
def helloworld(ob):
|
||||
print "Hello world"
|
||||
return ob
|
||||
|
||||
@helloworld
|
||||
def myfunc():
|
||||
print "my function"
|
||||
|
||||
myfunc()
|
||||
print myfunc
|
|
@ -0,0 +1,28 @@
|
|||
class Turbo(object):
|
||||
def turbo(self):
|
||||
return "VRRRRROUUUMMM"
|
||||
|
||||
class Prix(object):
|
||||
def get_prix(self):
|
||||
raise NotImplementedError
|
||||
|
||||
class Voiture(Prix, Turbo):
|
||||
def __init__(self, constructeur, vitesse_max=160):
|
||||
self.constructeur = constructeur
|
||||
self.vitesse_max = vitesse_max
|
||||
|
||||
def roule(self):
|
||||
return "vroummm"
|
||||
|
||||
def signaletique(self):
|
||||
return "constructeur : {0}, vitesse_max {1}".format(self.constructeur,
|
||||
self.vitesse_max)
|
||||
|
||||
class DoDoche(Voiture):
|
||||
def get_prix(self):
|
||||
return "4000"
|
||||
|
||||
def achete_voiture(voiture):
|
||||
if not hasattr(voiture, "get_prix"):
|
||||
raise TypeError("pas le bon type")
|
||||
return "prix de la voiture: {0} euros".format(voiture.get_prix())
|
|
@ -0,0 +1,20 @@
|
|||
liste = ['blah', 'blih', 'bluh']
|
||||
iterateur = liste.__iter__()
|
||||
print iterateur.next()
|
||||
print iterateur.next()
|
||||
print iterateur.next()
|
||||
print iterateur.next()
|
||||
#Traceback (most recent call last):
|
||||
# File '<stdin>', line 1, in <module>;
|
||||
#StopIteration
|
||||
|
||||
class Iterateur:
|
||||
i = 0
|
||||
def next(self):
|
||||
if self.i <= 10: raise StopIteration
|
||||
self.i += 1
|
||||
return 2**self.i
|
||||
def __iter__(self): return self
|
||||
|
||||
iterateur = Iterateur()
|
||||
for i in iterateur: print i
|
|
@ -0,0 +1,18 @@
|
|||
class NotFoundError(Exception):
|
||||
pass
|
||||
|
||||
class MaClasse:
|
||||
pass
|
||||
|
||||
class MaClasseDeux:
|
||||
pass
|
||||
|
||||
binding = dict(un=MaClasse, deux=MaClasseDeux)
|
||||
|
||||
def ma_factory(key):
|
||||
if key in binding:
|
||||
return binding[key]()
|
||||
else:
|
||||
return NotFoundError("keskece?")
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Add auto-completion and a stored history file of commands to your Python
|
||||
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
|
||||
# bound to the Esc key by default (you can change it - see readline docs).
|
||||
#
|
||||
# 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()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
class Sorter:
|
||||
def sort(self, list):
|
||||
for i in range(len(list) - 1):
|
||||
for j in range(i, len(list)):
|
||||
if self.compareItems(list[i], list[j]):
|
||||
list[i], list[j] = list[j], list[i]
|
||||
|
||||
def getName(self):
|
||||
return "Trieur de liste"
|
||||
|
||||
def getDescription(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def compareItems(self, item1, item2):
|
||||
raise NotImplementedError
|
||||
|
||||
class AscendantSorter(Sorter):
|
||||
def compareItems(self, item1, item2):
|
||||
return item1 >= item2
|
||||
def getDescription(self):
|
||||
return "Tri par ordre normal"
|
||||
def getName(self):
|
||||
return "Ascendant"
|
||||
|
||||
class DescendantSorter(Sorter):
|
||||
def compareItems(self, item1, item2):
|
||||
return item1 <= item2
|
||||
def getDescription(self):
|
||||
return "Tri par ordre inverse"
|
||||
|
||||
if __name__ == '__main__':
|
||||
list = ['b', 'e', 'a', 'c', 'z']
|
||||
s = AscendantSorter()
|
||||
s.sort(list)
|
||||
print list
|
||||
s = DescendantSorter()
|
||||
s.sort(list)
|
||||
print list
|
|
@ -0,0 +1,10 @@
|
|||
class Zone(object):
|
||||
def __init__(self, name, level=0):
|
||||
self.name = name
|
||||
self.level = level
|
||||
|
||||
def __add__(self, other):
|
||||
return Zone(self.name + other.name, level=self.level+other.level)
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.level, other.level)
|
|
@ -0,0 +1,22 @@
|
|||
class Wrap(object):
|
||||
def __init__(self, name, wrap):
|
||||
self.slots = ('_name', '_w')
|
||||
self._name = name or "wrapped_element"
|
||||
self._w = wrap
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in self.slots:
|
||||
return getattr(self, name)
|
||||
else:
|
||||
return getattr(self._w, name)
|
||||
|
||||
# def get_w(self, name):
|
||||
# return getattr(self._w, name)
|
||||
|
||||
# def set_w(self, name, value):
|
||||
# return setattr(self._w, name, value)
|
||||
|
||||
# _w = property (get_w, set_w)
|
||||
|
||||
def __repr__(self):
|
||||
return "[W_Element %s]"% repr(self._name)
|
Loading…
Reference in New Issue