# articles

feed_id: http://sametmax.com/?p=12742
title: 0bin.net est de nouveau en ligne Recently updated !
uri: 0bin-net-est-de-nouveau-en-ligne
url: http://sametmax.com/0bin-net-est-de-nouveau-en-ligne/
content:
<p><a href="http://sametmax.com/0bin-sest-fait-tej/">0bin était down</a>, on a supprimé la page en cause, et on l&#8217;a remis up.</p>
<p>On ne sait pas trop comment lutter contre ça. Même TPB a dû avoir 40 noms de domaine pour s&#8217;en sortir, et franchement on n&#8217;a pas envie de se taper autant de boulot pour un projet qui ne nous rapporte rien.</p>
<p>Que faire donc ?</p>
<p>D&#8217;abord, créer une admin pour 0bin pour supprimer une page plus facilement. Ça nous évitera de dépasser les délais la prochaine fois, car je n&#8217;étais pas dispo et Max ne savait pas comment faire. C&#8217;est pas que c&#8217;est compliqué, mais ça prend du temps, faut lire la doc, se connecter au serveur, etc. Et forcément, c&#8217;est du temps qu&#8217;on préfère passer sur Dota ou des projets qui rapportent des sous.</p>
<p>Ensuite, prendre le temps de vous rappeler que <a href="http://0bin.net/">0bin.net</a> n&#8217;est qu&#8217;une instance de 0bin. Un exemple. Multiplier les instances est encore le meilleur moyen d&#8217;avoir l&#8217;outil à disposition. Et le process est <a href="https://0bin.readthedocs.org/en/latest/">plutôt bien documenté</a>.</p>
<p>Mais une fois qu&#8217;on a posté son truc sur une instance, si elle tombe, que fait-on ?</p>
<p>Pour le moment on est baisé. </p>
<p>On pourrait donc imaginer de rajouter une fonction de distribution à 0bin. L&#8217;idée serait de se lier via une API simple à d&#8217;autres 0bin en qui on a confiance. Si quelqu&#8217;un poste sur l&#8217;un, tous les autres reçoivent une copie. Ainsi dans le lot, il y en aura bien un qui résistera. </p>
<p>Je me tâte à faire ça dans la semaine. Déjà 0bin a besoin d&#8217;un portage qui supporte Python 3. Ensuite quelques tests unitaires ne feraient pas de mal. Une fois que c&#8217;est fait, je freeze cette version, et je lance 1bin.net, la version suivante. Avec du crossbar.io, du angularjs et du mode distribué. Le truc sera plus lourd, uniquement compatible 2.7 et plus compliqué, donc je préfère en faire une version à part. </p>
<p>Ça se tente, voir si j&#8217;arrive à débloquer un peu de temps pour le faire, mais c&#8217;est pas impossible. Stay tuned.</p>


feed_id: http://sametmax.com/?p=12766
title: Quelle est la différence entre “bloquer” et “en cours d’exécution” ? Recently updated !
uri: Quelle-est-la-différence-entre-bloquer-et-en-cours-d-exéc
url: http://sametmax.com/quelle-est-la-difference-entre-bloquer-et-en-cours-dexecution/
content:
<p>On vous dit qu&#8217;il faut faire attention en utilisant des technologies non bloquantes, car si on bloque dans la boucle d&#8217;événement, on bloque tout le programme, et on perd l’intérêt de l&#8217;outil.</p>
<p>C&#8217;est vrai, mais que veut dire &#8220;bloquer&#8221; ?</p>
<p>Car si je fais :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1000000</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Mon programme va tourner longtemps, et la boucle d’événement va bloquer, n&#8217;est-ce pas ?</p>
<p>En fait, &#8220;bloquer&#8221; est un abus de langage car il y a plusieurs raisons pour bloquer. Dans notre contexte, il faudrait dire &#8220;bloquer en attente d&#8217;une entrée ou d&#8217;une sortie&#8221;. D&#8217;où l&#8217;appellation &#8220;Aynschronous non blocking I/O&#8221; des technos types NodeJS, Twisted, Tornado, Gevent, etc.</p>
<p>En effet, il faut distinguer deux causes d&#8217;attente à votre programme :</p>
<ul>
<li>Attendre que vos instructions se terminent. C&#8217;est être &#8220;en cours d&#8217;exécution&#8221;.</li>
<li>Attendre qu&#8217;un événement extérieur (écrire sur le disque, lire une socket, un clic de souris) arrive à sa conclusion. C&#8217;est bloquer sur de l&#8217;I/O.</li>
</ul>
<p>Le premier cas est impossible à éviter. Tout au mieux pouvons-nous répartir la charge du programme sur plusieurs cœurs, processeurs voire machines. Le code devra toujours attendre qu&#8217;il se termine, mais ça ira plus vite.</p>
<p>Dans le contexte de la programmation non bloquante telle qu&#8217;on vous en a parlé, on est donc dans le deuxième cas.</p>
<p>Il ne s&#8217;agit alors pas de s&#8217;interdire de faire des boucles ou autre opération longue (ou plutôt, c&#8217;est un problème d&#8217;optimisation ordinaire qui n&#8217;a rien à voir avec le fait de bloquer), il s&#8217;agit de ne pas &#8220;attendre à ne rien faire&#8221; quand une opération extérieure est en cours.</p>
<p>C&#8217;est ce que font naturellement NodeJS, Twisted, Tornado, Gevent &amp; Co. Quand on fait un échange HTTP, le bout de données part, puis le reste du code continue de tourner, passant à la tâche suivante, en attendant que le paquet traverse le réseau, atteigne l&#8217;autre machine, qui vous répond finalement. C&#8217;est ce temps, incompressible, sans contrôle de votre côté, durant lequel il ne faut pas bloquer. Le gain de perf est que votre programme ne se la touche pas pendant les temps d&#8217;attente, mais bien entendu que VOTRE, lui, code va prendre du temps et &#8220;bloquer&#8221; le processeur. Il faut bien qu&#8217;il s&#8217;exécute.</p>
<p>Ce qu&#8217;on entend donc par &#8220;il ne faut pas faire d&#8217;opération bloquante dans un code qui est déjà non bloquant&#8221; c&#8217;est &#8220;il ne faut pas utiliser un outil à l&#8217;API bloquante au milieu d&#8217;autres outils non bloquants&#8221;.</p>
<p>Par exemple, n&#8217;utilisez pas <a href="http://docs.python-requests.org/en/latest/">requests</a> avec Twisted, car requests est codé pour attendre sans rien faire jusqu’à obtenir une réponse à chaque requête, bloquant Twisted. Utilisez plutôt <a href="http://treq.readthedocs.org/en/latest/">treq</a>. C&#8217;est pareil pour la lecture d&#8217;un fichier, une requête de base de données, etc. Et il existe des boucles d&#8217;événements ailleurs que sur le serveur : une page Web possède sa propre boucle (c&#8217;est pour cela que tout JS est asynchrone), un toolkit GUI comme QT ou GTK aussi (c&#8217;est pour ça qu&#8217;ils utilisent la programmation événementielle), etc.</p>
<p>Maintenant vous allez me dire : mais pourquoi bloquer alors ? Pourquoi ne pas toujours éviter de bloquer ?</p>
<p>Et bien parce que si on ne bloque pas, on ne peut pas écrire un programme ligne à ligne. On est obligé d&#8217;adopter un style de programmation asynchrone puisqu&#8217;on ne sait pas quand le résultat de certaines lignes va arriver. Ça veut dire des callbacks, ou des futures, ou des coroutines, ou du message passing&#8230; Bref, un truc plus compliqué. Or, on n&#8217;a pas forcément besoin de ce niveau de performance. En fait, la grande majorité des programmes n&#8217;ont pas besoin de ce niveau de performance. Donc, on bloque en attendant, non pas Godot, mais l&#8217;I/O, parce que c&#8217;est plus simple à écrire. Pour pas se faire chier.</p>
<p>Il y a bien des moyens de contourner ce problème : les threads, le multiprocessing, les coroutines, etc. Parfois même, on ignore le problème : bloquer quelques ms au milieu d&#8217;une boucle d’événements une fois par seconde n&#8217;est pas un drame. Une fois que j&#8217;ai fini le dossier sur les tests unitaires, je vous ferai un dossier sur la programmation non bloquante, avec aussi une esquisse de la parallélisation.</p>
<p>En attendant, ne stressez pas parce que votre code &#8220;bloque&#8221; parce qu&#8217;il travaille longtemps, assurez-vous juste que les APIs que vous utilisez ne bloquent pas pendant l&#8217;I/O, et vous êtes ok.</p>
<p>Et comment savoir ? Et bien si une donnée rentre ou sort de votre programme (ça ne fait pas partie du code source), c&#8217;est de l&#8217;I/O. Si votre code ressemble à ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">res <span style="color: #66cc66;">=</span> faire_operation_sur_IO<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
faire_un_truc_avec_le_res<span style="color: black;">&#40;</span>res<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Alors votre outil est bloquant, puisque qu&#8217;il compte sur le fait que la deuxième ligne sera exécutée à coup sûr quand la première sera terminée. Un outil non bloquant exigera quelque chose pour gérer le retour du résultat plus tard: un callback, une promesse, un <code>yield</code>&#8230;</p>


feed_id: http://sametmax.com/?p=12815
title: Des bouts de Python cachés Recently updated !
uri: Des-bouts-de-Python-cachés-Recently-updated
url: http://sametmax.com/des-bouts-de-python-caches/
content:
<p>J&#8217;aime bien fouiner pour trouver des petits trucs insolites dans mes techos. Cet <a href="http://stackoverflow.com/questions/101268/hidden-features-of-python?page=3&#038;tab=oldest#tab-top">excellent post</a> sur SO est un bon début, mais on découvre toujours de nouvelles choses.</p>
<h2>ChainMap</h2>
<p>Vous vous souvenez de <a href="http://sametmax.com/chercher-dans-plusieurs-dicts-a-la-fois-avec-chainmap/">ChainMap</a> ? C&#8217;est top, mais uniquement en Python 3. </p>
<p>Et bien il existe une version cachée en Python 2 :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">ConfigParser</span> <span style="color: #ff7700;font-weight:bold;">import</span> _Chainmap <span style="color: #ff7700;font-weight:bold;">as</span> ChainMap</pre></td></tr></table></div>

<p>C&#8217;est pas aussi complet (il n&#8217;y a pas les méthodes <code>new_child</code> et <code>parents</code>), mais ça peut servir.</p>
<p>Si néanmoins, vous avez besoin de l&#8217;implémentation complète, il existe <a href="https://github.com/justanr/Py2ChainMap">un backport</a> installable avec <a href="http://sametmax.com/votre-python-aime-les-pip/">pip</a> :</p>
<p><code lang="bash">pip install Py2ChainMap</code></p>
<h2>str.startswith, str.endswith et un tuple</h2>
<p>Pour beaucoup de situations, une regex en Python, c&#8217;est overkill. On a <code>in</code> pour vérifier qu&#8217;une chaîne en contient une autre. Et on a <code>str.startswith()</code> et <code>str.endswith()</code> pour vérifier qu&#8217;une chaîne commence ou finit par une autre. Avec des <code>strip()</code>/<code>split()</code>/<code>lower()</code>, on finit souvent par s&#8217;en sortir, et l&#8217;usage de toutes ces méthodes est en général plus performant que d&#8217;utiliser <code>re</code>.</p>
<p>Mais si vous avez plusieurs chaînes à vérifier ? Pas de problème, <code>str.startswith()</code> et <code>str.endswith()</code> acceptent aussi des tuples :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;Je suis une chaîne qui a du caractère&quot;</span>.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Tu'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">False</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;Je suis une chaîne qui a du caractère&quot;</span>.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Je'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">True</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;Je suis une chaîne qui a du caractère&quot;</span>.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Tu'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Je'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">True</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span></pre></td></tr></table></div>

<h2>Les espaces entre une instance et son attribut sont ignorés</h2>
<p>Bien que la deuxième ligne soit très moche, elle est parfaitement valide :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;Yolo&quot;</span>.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'YOLO'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;Yolo&quot;</span>           .<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'YOLO'</span></pre></td></tr></table></div>

<p>Or on peut intercepter l&#8217;accès aux attributs à la volée en Python grâce aux <a href="http://sametmax.com/le-guide-ultime-et-definitif-sur-la-programmation-orientee-objet-en-python-a-lusage-des-debutants-qui-sont-rassures-par-les-textes-detailles-qui-prennent-le-temps-de-tout-expliquer-partie-6/">méthodes magiques</a>.</p>
<p>Ça veut dire qu&#8217;on peut implémenter des &#8220;symboles&#8221; en Python.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> SymbolMaker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
    symbols <span style="color: #66cc66;">=</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getattr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span>:
        symbols.<span style="color: black;">add</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> make_symbol <span style="color: #66cc66;">=</span> SymbolMaker<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> make_symbol   .<span style="color: black;">start</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> make_symbol   .<span style="color: black;">end</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> SymbolMaker.<span style="color: black;">symbols</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'end'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'start'</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>Je n&#8217;ai pas dit qu&#8217;on devrait le faire, j&#8217;ai dit qu&#8217;on pouvait :) D&#8217;ailleurs, y en a qui <a href="http://entrian.com/goto/">l&#8217;utilisent pour implémenter <code>GOTO</code> en Python</a>. The troll is strong with this &#8220;feature&#8221;.</p>


feed_id: http://sametmax.com/?p=12693
title: Introduction au currying Recently updated !
uri: Introduction-au-currying
url: http://sametmax.com/introduction-au-currying/
content:
<p>Le currying (ou Curryfication pour les frencofans) est le nom donné à une technique de programmation qui consiste à créer une fonction à partir d&#8217;une autre fonction et d&#8217;une liste partielle de paramètres destinés à celle-ci. On retrouve massivement cette technique en programmation fonctionnelle puisqu&#8217;elle permet de créer une fonction pure à partir d&#8217;une autre fonction pure. C&#8217;est une forme de réutilisabilité de code.</p>
<p>La forme la plus simple de currying est de réécrire une fonction appelant l&#8217;autre. Par exemple, soit une fonction pour multiplier tous les éléments d&#8217;un itérable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> multiply<span style="color: black;">&#40;</span>iterable<span style="color: #66cc66;">,</span> number<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Multiplie tous les éléments d'un itérable par un nombre.
&nbsp;
        Exemple :
&nbsp;
            &gt;&gt;&gt; list(multiply([1, 2, 3], 2))
            [2, 4, 6]
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>x * number <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On peut ensuite créer une fonction qui multipliera par 2 tous les éléments d&#8217;un itérable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> doubled<span style="color: black;">&#40;</span>iterable<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Multiplie tous les éléments d'un itérable par un 2.
&nbsp;
        Exemple :
&nbsp;
            &gt;&gt;&gt; list(doubled([1, 2, 3]))
            [2, 4, 6]
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> multiply<span style="color: black;">&#40;</span>iterable<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>C&#8217;est une forme de currying. On créé une fonction qui fait ce que fait une autre fonction, mais avec des arguments par défaut.</p>
<p>Python possède une fonction pour faire ça automatiquement avec n&#8217;importe quelle fonction :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">from</span> functools <span style="color: #ff7700;font-weight:bold;">import</span> partial 
<span style="color: #66cc66;">&gt;&gt;&gt;</span> tripled <span style="color: #66cc66;">=</span> partial<span style="color: black;">&#40;</span>multiply<span style="color: #66cc66;">,</span> number<span style="color: #66cc66;">=</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># on curryfie ici</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>tripled<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># nouvelle fonction avec un seul argument</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">9</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Cela marche car, je vous le rappelle, les fonctions sont des objets en Python. On peut mettre une fonction (je ne parle pas de son résultat) dans une variable, passer une fonction en paramètre ou retourner une fonction dans une autre fonction. <strong>Les fonctions sont manipulables</strong>.</p>
<p>Il n&#8217;est pas rare d&#8217;utiliser les fonctions anonymes comme outils curryfication. En Python, on ferait ça avec une <a href="http://sametmax.com/fonctions-anonymes-en-python-ou-lambda/">lambda</a> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> tripled <span style="color: #66cc66;">=</span> <span style="color: #ff7700;font-weight:bold;">lambda</span> x: multiple<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> 
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>tripled<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">9</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Certains outils, comme <a href="http://buzzdecafe.github.io/code/2014/05/16/introducing-ramda/">Ramda</a> en Javascript, vont plus loin, et exposent des fonctions qui se curryfient automatiquement.</p>
<p>Pour ce faire, il faut inverser l&#8217;ordre qu&#8217;on mettrait intuitivement aux arguments dans la déclaration d&#8217;une fonction :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># au lieu de multiply(iterable, number), on a :</span>
<span style="color: #ff7700;font-weight:bold;">def</span> multiply<span style="color: black;">&#40;</span>number<span style="color: #66cc66;">,</span> iterable<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Si on a pas d'itérable passé, on curryfie</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> iterable <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> partial<span style="color: black;">&#40;</span>multiply<span style="color: #66cc66;">,</span> number<span style="color: #66cc66;">=</span>number<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>x * number <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ainsi :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>multiply<span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># pas de currying</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> quintuple <span style="color: #66cc66;">=</span> multiply<span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># currying automatique</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>quintuple<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">15</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>L’intérêt de ce style, c&#8217;est qu&#8217;on peut composer des traitements à partir de plusieurs sous traitements, presque déclarativement :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> remove<span style="color: black;">&#40;</span><span style="color: #008000;">filter</span><span style="color: #66cc66;">,</span> iterable<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Retire tous les éléments d'un itérable correspondant au filtre.
&nbsp;
        Exemple :
&nbsp;
            &gt;&gt;&gt; list(remove(lambda x: x &gt;= 4, [1, 2, 3, 4, 5]))
            [1, 2, 3]
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> iterable <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> partial<span style="color: black;">&#40;</span>remove<span style="color: #66cc66;">,</span> <span style="color: #008000;">filter</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> smalls <span style="color: #66cc66;">=</span> remove<span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: x <span style="color: #66cc66;">&gt;=</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>smalls<span style="color: black;">&#40;</span>tripled<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># le traitement est auto descriptif</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Néanmoins, il faut savoir que ce style n&#8217;est pas pythonique. En effet, en Python on préférera généralement utiliser des suites suite de générateurs. Soit par <a href="http://sametmax.com/python-love-les-listes-en-intention-partie-2/">intention</a>, soit via <a href="http://sametmax.com/comment-utiliser-yield-et-les-generateurs-en-python/">yield</a>.</p>
<p>Notre exemple serait alors :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> tripled <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>x * <span style="color: #ff4500;">3</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> smalls <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> tripled <span style="color: #ff7700;font-weight:bold;">if</span> x <span style="color: #66cc66;">&lt;=</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>smalls<span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>De plus, cette technique suppose qu&#8217;on ne profitera pas de certaines fonctionnalités, comme les paramètres par défaut des fonctions Python.</p>
<p>C&#8217;est toutefois une bonne chose à connaître. C&#8217;est occasionnellement utile en Python et peut produire des solutions très élégantes. C&#8217;est également une bonne chose à comprendre pour aborder d&#8217;autres langages plus fonctionnels qui les utilisent bien plus comme le Javascript, le Lisp, ou carrément le Haskell.</p>


feed_id: http://sametmax.com/?p=12854
title: Qu’est-ce qu’une coroutine en Python, et à quoi ça sert ?
uri: Qu-est-ce-qu-une-coroutine-en-Python-et-à-quoi-ça-sert
url: http://sametmax.com/quest-ce-quune-coroutine-en-python-et-a-quoi-ca-sert/
content:
<p>Si vous avez aimé les générateurs, vous avez du creuser un peu <code>yield</code> et vous apercevoir qu&#8217;on pouvait créer des coroutines avec. Mais sans vraiment comprendre ce que ça faisait.</p>
<p>On va se faire une petit intro. C&#8217;est un sujet vraiment avancé, donc si vous avez autre chose de moins compliqué à comprendre en Python (n&#8217;importe quoi à part les métaclasses :)), ne vous prenez pas la tête sur cet article. Ecoutez juste la musique :</p>
<p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/zqKZ_WIK5ms?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p>
<p>D&#8217;abord, rappel sur le fonctionnement des générateurs (qui sont un prérequis de l&#8217;article, donc si besoin, relisez le <a href="http://sametmax.com/comment-utiliser-yield-et-les-generateurs-en-python/">tuto dédié</a>) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> soleil<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Premier next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 1'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Deuxième next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 2'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">2</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Troisième next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 3'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">3</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># pas de quatrième next(),</span>
    <span style="color: #808080; font-style: italic;"># donc on ne passe jamais ici</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Pas vu'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># rappel, ceci ne déclenche pas le code </span>
<span style="color: #808080; font-style: italic;"># de soleil() puisqu'il y a yield dedans</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Creation du generateur&quot;</span><span style="color: black;">&#41;</span>
undeuxtrois <span style="color: #66cc66;">=</span> soleil<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On execute le code jusqu'au yield 1</span>
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>undeuxtrois<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On execute le code jusqu'au yield 2</span>
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>undeuxtrois<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On execute le code jusqu'au yield 3</span>
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>undeuxtrois<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Good bye'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## Premier next()</span>
<span style="color: #808080; font-style: italic;">## Yield 1</span>
<span style="color: #808080; font-style: italic;">## res = 1</span>
<span style="color: #808080; font-style: italic;">## Deuxième next()</span>
<span style="color: #808080; font-style: italic;">## Yield 2</span>
<span style="color: #808080; font-style: italic;">## res = 2</span>
<span style="color: #808080; font-style: italic;">## Troisième next()</span>
<span style="color: #808080; font-style: italic;">## Yield 3</span>
<span style="color: #808080; font-style: italic;">## res = 3</span>
<span style="color: #808080; font-style: italic;">## Good bye</span></pre></td></tr></table></div>

<p>Chaque fois qu&#8217;on appelle <code>next()</code> sur le générateur, il va exécuter le code jusqu&#8217;au prochain <code>yield</code>, et retourner la valeur de celui-ci, puis mettre le générateur en pause.</p>
<p>On peut assigner le résultat d&#8217;un <code>yield</code>, mais si on fait des <code>next()</code>, on obtient toujours <code>None</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> lune<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Premier next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 1'</span><span style="color: black;">&#41;</span>
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Deuxième next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Avant le yield 2, x = %s'</span> % x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 2'</span><span style="color: black;">&#41;</span>
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Troisième next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Avant le yield 3, x = %s'</span> % x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 3'</span><span style="color: black;">&#41;</span>
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Pas vu'</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Creation du generateur&quot;</span><span style="color: black;">&#41;</span>
generateur <span style="color: #66cc66;">=</span> lune<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
res <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Good bye'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## Creation du generateur</span>
<span style="color: #808080; font-style: italic;">## Premier next()</span>
<span style="color: #808080; font-style: italic;">## Yield 1</span>
<span style="color: #808080; font-style: italic;">## res = 1</span>
<span style="color: #808080; font-style: italic;">## Deuxième next()</span>
<span style="color: #808080; font-style: italic;">## Avant le yield 2, x = None</span>
<span style="color: #808080; font-style: italic;">## Yield 2</span>
<span style="color: #808080; font-style: italic;">## res = 2</span>
<span style="color: #808080; font-style: italic;">## Troisième next()</span>
<span style="color: #808080; font-style: italic;">## Avant le yield 3, x = None</span>
<span style="color: #808080; font-style: italic;">## Yield 3</span>
<span style="color: #808080; font-style: italic;">## res = 3</span>
<span style="color: #808080; font-style: italic;">## Good bye</span></pre></td></tr></table></div>

<p>La raison est que cette valeur doit venir de l&#8217;extérieur. Pour la fournir, il faut utiliser la méthode <code>send()</code> et non la fonction <code>next()</code>.</p>
<p>Mais elle ne fonctionne pas du tout pareil. En fait, si on l&#8217;appelle cash pistache, ça plante :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Creation du generateur&quot;</span><span style="color: black;">&#41;</span>
generateur <span style="color: #66cc66;">=</span> lune<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
res <span style="color: #66cc66;">=</span> generateur.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;A&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## Creation du generateur</span>
<span style="color: #808080; font-style: italic;">## Traceback (most recent call last):</span>
<span style="color: #808080; font-style: italic;">## File &quot;test.py&quot;, line 24, in </span>
<span style="color: #808080; font-style: italic;">##   res = generateur.send(&quot;A&quot;)</span>
<span style="color: #808080; font-style: italic;">##     TypeError: can't send non-None value to a just-started generator</span></pre></td></tr></table></div>

<p>C&#8217;est parce que, contrairement à <code>next()</code> qui va jusqu&#8217;au prochain <code>yield</code>, <code>send()</code> PART du dernier <code>yield</code> atteint pour aller au suivant.</p>
<p>Il faut donc d&#8217;abord arriver à un premier <code>yield</code> avant de faire un <code>send()</code>. On peut le faire en utilisant au moins un <code>next()</code>.</p>
<p>Voici donc notre nouveau code :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> lune<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'On fait au moins un next()'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 1'</span><span style="color: black;">&#41;</span>
&nbsp;
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Premier send(), x = %s'</span> % x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 2'</span><span style="color: black;">&#41;</span>
&nbsp;
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Deuxième send(), x = %s'</span> % x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Yield 3'</span><span style="color: black;">&#41;</span>
&nbsp;
    x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Comme on fait un next() et 3 send()</span>
    <span style="color: #808080; font-style: italic;"># on arrive là</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Troisième send(), x = %s'</span> % x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'YOLOOOOO'</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Creation du generateur&quot;</span><span style="color: black;">&#41;</span>
generateur <span style="color: #66cc66;">=</span> lune<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Ou generateur.send(None)</span>
&nbsp;
res <span style="color: #66cc66;">=</span> generateur.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;A&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
res <span style="color: #66cc66;">=</span> generateur.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;B&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
&nbsp;
res <span style="color: #66cc66;">=</span> generateur.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;C&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'res = %s'</span> % res<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Good bye'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## Creation du generateur</span>
<span style="color: #808080; font-style: italic;">## On fait au moins un next()</span>
<span style="color: #808080; font-style: italic;">## Yield 1</span>
<span style="color: #808080; font-style: italic;">## Premier send(), x = A</span>
<span style="color: #808080; font-style: italic;">## Yield 2</span>
<span style="color: #808080; font-style: italic;">## res = 2</span>
<span style="color: #808080; font-style: italic;">## Deuxième send(), x = B</span>
<span style="color: #808080; font-style: italic;">## Yield 3</span>
<span style="color: #808080; font-style: italic;">## res = 3</span>
<span style="color: #808080; font-style: italic;">## Troisième send(), x = C</span>
<span style="color: #808080; font-style: italic;">## YOLOOOOO</span>
<span style="color: #808080; font-style: italic;">## Traceback (most recent call last):</span>
<span style="color: #808080; font-style: italic;">##   File &quot;test.py&quot;, line 33, in </span>
<span style="color: #808080; font-style: italic;">##     res = generateur.send(&quot;C&quot;)</span>
<span style="color: #808080; font-style: italic;">## StopIteration</span></pre></td></tr></table></div>

<p><code>send()</code> agit donc comme <code>next()</code>. Il va aller jusqu&#8217;au prochain <code>yield</code> et lui faire retourner sa valeur. Mais il y a des différences :</p>
<ul>
<li>Elle doit partir d&#8217;un précédent <code>yield</code>.</li>
<li>Donc il faut au moins avoir atteint un <code>yield</code> via <code>next()</code>.</li>
<li>Ce précédent <code>yield</code> peut retourner une valeur : celle passée via <code>send(val).</code></li>
</ul>
<p>La valeur peut être n&#8217;importe quel objet : string, int, classe, list, etc.</p>
<p>Bref, <code>send()</code> permet de créer un générateur donc le comportement n&#8217;est pas figé dans le marbre.</p>
<p>Par exemple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> creer_fontaine<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    contenu <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;soda&quot;</span> 
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        x <span style="color: #66cc66;">=</span> <span style="color: #ff7700;font-weight:bold;">yield</span> contenu
        <span style="color: #ff7700;font-weight:bold;">if</span> x:
            contenu <span style="color: #66cc66;">=</span> x
&nbsp;
&nbsp;
fontaine <span style="color: #66cc66;">=</span> creer_fontaine<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>next<span style="color: black;">&#40;</span>fontaine<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># on change le contenu de la fontaine</span>
fontaine.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;lait&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>next<span style="color: black;">&#40;</span>fontaine<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
soda
soda
soda
soda
soda
lait
lait
lait
lait
lait</pre></td></tr></table></div>

<p>On peut même s&#8217;en servir pour faire des trucs chelou comme injecter une dépendance à la volée ou contrôler le flux de son générateur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> fuckitjaiplusdenomcool<span style="color: black;">&#40;</span>start<span style="color: #66cc66;">,</span> inc<span style="color: #66cc66;">=</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: x + <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
    x <span style="color: #66cc66;">=</span> start
    <span style="color: #808080; font-style: italic;"># on controle le flux du générateur en changeant</span>
    <span style="color: #808080; font-style: italic;"># la valeur de x qui peut tout stopper</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> x:
        sent <span style="color: #66cc66;">=</span> <span style="color: #ff7700;font-weight:bold;">yield</span> x
        <span style="color: #ff7700;font-weight:bold;">if</span> sent:
            inc <span style="color: #66cc66;">=</span> sent
        <span style="color: #808080; font-style: italic;"># la valeur de x dépend de ce bout de code</span>
        <span style="color: #808080; font-style: italic;"># qui est injectable</span>
        x <span style="color: #66cc66;">=</span> inc<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
generateur <span style="color: #66cc66;">=</span> fuckitjaiplusdenomcool<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> generateur:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> x &amp;gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">10</span>:
        <span style="color: #808080; font-style: italic;"># si on dépasse 10, on décrémente</span>
        generateur.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: x - <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## 1</span>
<span style="color: #808080; font-style: italic;">## 2</span>
<span style="color: #808080; font-style: italic;">## 3</span>
<span style="color: #808080; font-style: italic;">## 4</span>
<span style="color: #808080; font-style: italic;">## 5</span>
<span style="color: #808080; font-style: italic;">## 6</span>
<span style="color: #808080; font-style: italic;">## 7</span>
<span style="color: #808080; font-style: italic;">## 8</span>
<span style="color: #808080; font-style: italic;">## 9</span>
<span style="color: #808080; font-style: italic;">## 10</span>
<span style="color: #808080; font-style: italic;">## 11</span>
<span style="color: #808080; font-style: italic;">## 9</span>
<span style="color: #808080; font-style: italic;">## 8</span>
<span style="color: #808080; font-style: italic;">## 7</span>
<span style="color: #808080; font-style: italic;">## 6</span>
<span style="color: #808080; font-style: italic;">## 5</span>
<span style="color: #808080; font-style: italic;">## 4</span>
<span style="color: #808080; font-style: italic;">## 3</span>
<span style="color: #808080; font-style: italic;">## 2</span>
<span style="color: #808080; font-style: italic;">## 1</span></pre></td></tr></table></div>

<p>Mais bon, pas la peine de rentrer dans des cas si compliqués.</p>
<p>Néanmoins, un cas d&#8217;usage de <code>send()</code> est de créer une coroutine. Une coroutine est simplement une tâche.</p>
<p>C&#8217;est un bout de code qui fait une tache, avec un bout d&#8217;initialisation, et un bout de finalisation, et un bout d&#8217;exécution.</p>
<p>Par exemple, j&#8217;ai un filtre qui prend un fichier rempli d&#8217;adresses IP. Il va recevoir du texte, et si le texte contient une adresse IP, il le signale, et remplit un compteur sur le disque.</p>
<p>Si on devait coder ça en objet on dirait :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Filtre:
&nbsp;
    <span style="color: #808080; font-style: italic;"># initialisation</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> ipfile<span style="color: #66cc66;">,</span> counterfile<span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>ipfile<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
            <span style="color: #008000;">self</span>.<span style="color: black;">banned_ips</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>counterfile<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
            <span style="color: #008000;">self</span>.<span style="color: black;">count</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>counterfile<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> check<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> line<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># récupère les ip et check celles qui sont </span>
        <span style="color: #808080; font-style: italic;"># à filtrer</span>
        ips <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span> r<span style="color: #483d8b;">'[0-9]+(?:<span style="color: #000099; font-weight: bold;">\.</span>[0-9]+){3}'</span><span style="color: #66cc66;">,</span> line<span style="color: black;">&#41;</span>
        bad_ips <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>ip <span style="color: #ff7700;font-weight:bold;">for</span> ip <span style="color: #ff7700;font-weight:bold;">in</span> ips <span style="color: #ff7700;font-weight:bold;">if</span> ip <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">banned_ips</span><span style="color: black;">&#93;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># si il y a des ip à filtrer, on incrémente le compteur</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> bad_ips:
            <span style="color: #008000;">self</span>.<span style="color: black;">count</span> +<span style="color: #66cc66;">=</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>bad_ips<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">seek</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">count</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># on retourn les valeurs trouvées</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> bad_ips
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> close<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On l&#8217;utiliserait comme ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">f <span style="color: #66cc66;">=</span> Filtre<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/chemin/vers/liste&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;/chemin/vers/counteur&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> text:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>f.<span style="color: black;">check</span><span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Notez que pour une tâche, l&#8217;API est toujours la même : initialiser, exécuter la tâche autant de fois que nécessaire, puis finaliser.</p>
<p>Les coroutines sont un mot qu&#8217;on met sur ce principe (initialiser, exec, finaliser), mais avec une API sous forme de générateur. Le même code en coroutine :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> filtre<span style="color: black;">&#40;</span>ipfile<span style="color: #66cc66;">,</span> counterfile<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #808080; font-style: italic;"># Initialisation</span>
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>ipfile<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        banned_ips <span style="color: #66cc66;">=</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>counterfile<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        count <span style="color: #66cc66;">=</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    counterfile <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>counterfile<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Exécution</span>
    bad_ips <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            <span style="color: #808080; font-style: italic;"># entree et sortie de notre send(), qui équivaut</span>
            <span style="color: #808080; font-style: italic;"># aux params de &quot;check()&quot;</span>
            line <span style="color: #66cc66;">=</span> <span style="color: #ff7700;font-weight:bold;">yield</span> bad_ips
&nbsp;
        <span style="color: #808080; font-style: italic;"># GeneratorExit est levé is on fait generator.close()</span>
        <span style="color: #808080; font-style: italic;"># On ne peut pas ignorer cette erreur, mais</span>
        <span style="color: #808080; font-style: italic;"># on peut mettre du code de finalisation ici.</span>
        <span style="color: #808080; font-style: italic;"># Bon en vrai faudrait faire un finally quelque part</span>
        <span style="color: #808080; font-style: italic;"># mais c'est pour l'exemple bande de peer reviewers</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> GeneratorExit:
                <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        ips <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span> r<span style="color: #483d8b;">'[0-9]+(?:<span style="color: #000099; font-weight: bold;">\.</span>[0-9]+){3}'</span><span style="color: #66cc66;">,</span> line<span style="color: black;">&#41;</span>
        bad_ips <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>ip <span style="color: #ff7700;font-weight:bold;">for</span> ip <span style="color: #ff7700;font-weight:bold;">in</span> ips <span style="color: #ff7700;font-weight:bold;">if</span> ip <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">banned_ips</span><span style="color: black;">&#93;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># si il y a des ip à filtrer, on incrémente le compteur</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> bad_ips:
            <span style="color: #008000;">self</span>.<span style="color: black;">count</span> +<span style="color: #66cc66;">=</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>bad_ips<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">seek</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">counterfile</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">count</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On l&#8217;utiliserait comme ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">f <span style="color: #66cc66;">=</span> filtre<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/chemin/vers/liste&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;/chemin/vers/counteur&quot;</span><span style="color: black;">&#41;</span>
next<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> text:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>f.<span style="color: black;">send</span><span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># ceci raise GeneratorExit</span>
f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Généralement on veut pas se faire chier à appeler <code>next()</code> à chaque fois, donc toutes les libs à base de coroutine ont ce genre de décorateur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> coroutine<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> wrapper<span style="color: black;">&#40;</span>*arg<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
        generator <span style="color: #66cc66;">=</span> func<span style="color: black;">&#40;</span>*arg<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
        next<span style="color: black;">&#40;</span>generator<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> generator
    <span style="color: #ff7700;font-weight:bold;">return</span> wrapper</pre></td></tr></table></div>

<p>Afin de pouvoir faire ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>coroutine
<span style="color: #ff7700;font-weight:bold;">def</span> filtre<span style="color: black;">&#40;</span>ipfile<span style="color: #66cc66;">,</span> counterfile<span style="color: black;">&#41;</span>:
    ...</pre></td></tr></table></div>

<p>Ca a un double usage : ça appelle <code>next()</code> automatiquement, et ça signale que la fonction est destinée à être utilisée comme coroutine.</p>
<p>Mais voilà, c&#8217;est tout, une coroutine c&#8217;est juste ça : utiliser un générateur pour faire une tâche qui consiste à s&#8217;initialiser, faire un traitement plusieurs fois, et optionellement, se finaliser. On utilisera une coroutine pour ne pas reinventer la roue car c&#8217;est un problème bien défini, qui a une solution. D&#8217;autant qu&#8217;une coroutine bouffe moins de ressources qu&#8217;une classe.</p>
<p>Les usages avancés des coroutines impliquent de chaîner plusieurs coroutines, comme des tuyaux.</p>
<p>Souvenez-vous, en Python il est courant de chaîner des générateurs :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> mettre_au_carre<span style="color: black;">&#40;</span>iterable<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        <span style="color: #ff7700;font-weight:bold;">yield</span> x * x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> filtrer_les_pairs<span style="color: black;">&#40;</span>iterable<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        <span style="color: #ff7700;font-weight:bold;">if</span> x % <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>:
            <span style="color: #ff7700;font-weight:bold;">yield</span> x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> strigifier<span style="color: black;">&#40;</span>iterable<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># on pipe les données d'un générateur à l'autre</span>
nombres <span style="color: #66cc66;">=</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
carres <span style="color: #66cc66;">=</span> mettre_au_carre<span style="color: black;">&#40;</span>nombres<span style="color: black;">&#41;</span>
carres_pairs <span style="color: #66cc66;">=</span> filtrer_les_pairs<span style="color: black;">&#40;</span>carres<span style="color: black;">&#41;</span>
fete_du_string <span style="color: #66cc66;">=</span> strigifier<span style="color: black;">&#40;</span>carres_pairs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> fete_du_string:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">repr</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## '0'</span>
<span style="color: #808080; font-style: italic;">## '4'</span>
<span style="color: #808080; font-style: italic;">## '16'</span>
<span style="color: #808080; font-style: italic;">## '36'</span>
<span style="color: #808080; font-style: italic;">## '64'</span></pre></td></tr></table></div>

<p>On peut faire pareil avec les coroutines. Cependant, la logique est inversée : au lieu de lire les données, on les envoie :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>coroutine
<span style="color: #ff7700;font-weight:bold;">def</span> mettre_au_carre<span style="color: black;">&#40;</span>ouput<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span><span style="color: black;">&#41;</span>
        ouput.<span style="color: black;">send</span><span style="color: black;">&#40;</span>x * x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>coroutine
<span style="color: #ff7700;font-weight:bold;">def</span> filtrer_les_paires<span style="color: black;">&#40;</span>ouput<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> x % <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>:
            ouput.<span style="color: black;">send</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>coroutine
<span style="color: #ff7700;font-weight:bold;">def</span> strigifier<span style="color: black;">&#40;</span>ouput<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span><span style="color: black;">&#41;</span>
        ouput.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>coroutine
<span style="color: #ff7700;font-weight:bold;">def</span> afficher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        x <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">yield</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
nombres <span style="color: #66cc66;">=</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># chaque coroutine est la sortie d'une autre</span>
afficheur <span style="color: #66cc66;">=</span> afficher<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
fete_du_string <span style="color: #66cc66;">=</span> strigifier<span style="color: black;">&#40;</span>afficheur<span style="color: black;">&#41;</span>
paires <span style="color: #66cc66;">=</span> filtrer_les_paires<span style="color: black;">&#40;</span>fete_du_string<span style="color: black;">&#41;</span>
carre <span style="color: #66cc66;">=</span> mettre_au_carre<span style="color: black;">&#40;</span>paires<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># on envoit les données vers la première coroutine</span>
<span style="color: #808080; font-style: italic;"># et elle fait suivre aux autres</span>
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> nombres:
    carre.<span style="color: black;">send</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## '0'</span>
<span style="color: #808080; font-style: italic;">## '4'</span>
<span style="color: #808080; font-style: italic;">## '16'</span>
<span style="color: #808080; font-style: italic;">## '36'</span>
<span style="color: #808080; font-style: italic;">## '64'</span></pre></td></tr></table></div>

<p>Vous allez me dire : &#8220;ça fait la même chose, et c&#8217;est plus compliqué, quel interêt ?&#8221;.</p>
<p>En fait, ça ne fait pas exactement la même chose.</p>
<p>Dans le cas des générateurs ordinaires, on déclenche le traitement par la fin. On fait une boucle qui demande quelle est la prochaine donnée, et si il y en a une, on l&#8217;affiche. C&#8217;est pratique si on sait qu&#8217;on a des données sous la main car on demande (<code>next()</code> est appelée par la boucle <code>for</code>) la donnée suivante à chaque fois : c&#8217;est du PULL.</p>
<p>Mais que se passe-t-il si on n&#8217;a pas encore les données ? Si on traite des données qui arrivent par évenement ?</p>
<p>Par exemple, si on écrit un serveur HTTP qui doit réagir aux requêtes ?</p>
<p>Dans ce cas, on ne peut envoyer (<code>send()</code>) la donnée suivante dans notre pipeline de générateurs uniquement quand elle arrive, et les coroutines font exactement cela : c&#8217;est du PUSH.</p>
<p>En résumé :</p>
<ul>
<li><code>yield</code> permet de faire des générateurs</li>
<li>On peut demander la prochaine valeur du générateur avec <code>next()</code>. Dans ce cas, le code s&#8217;exécute jusqu&#8217;au prochain <code>yield</code>.</li>
<li>On peut envoyer une valeur au générateur avec <code>send()</code>. Dans ce cas, on DOIT partir d&#8217;un <code>yield</code> existant duquel on récupère la valeur envoyée via une assignation. Donc il faut au moins un <code>next()</code> avant d&#8217;utiliser un <code>send()</code> et un signe égal sur le <code>yield</code>.</li>
<li><code>send()</code> va aussi aller au prochain <code>yield</code> et retourner sa valeur.</li>
<li>Une coroutine n&#8217;est qu&#8217;une formalisation de la manière d&#8217;éffectuer une tâche avec un init, une exécution et une finalisation optionelle en utilisant un générateur. C&#8217;est une solution générique à un problème courant, mais plus léger qu&#8217;une classe.</li>
<li>Généralement on décore les générateurs coroutines avec un décorateur <code>@coroutine</code> pour s&#8217;éviter d&#8217;appeler <code>next()</code> à la main et notifier l&#8217;usage qu&#8217;il est fait de ce générateur.</li>
<li>On peut chaîner des coroutines comme on chaîne des générateurs, mais au lieu de lire les données une à une (PULL), on les envoie une par une (PUSH). Cela est pratique quand on ne sait pas à l&#8217;avance quand une nouvelle donnée va arriver.</li>
</ul>
<p>Si vous êtes arrivé jusqu&#8217;ici, vous méritez un cookie.</p>
<p>Ca tombe bien, ce blog utilise des cookies, et la loi m&#8217;oblige à vous le notifier.</p>


feed_id: http://sametmax.com/?p=12867
title: Quand ne pas utiliser Python ? Recently updated !
uri: Quand-ne-pas-utiliser-Python-Recently-updated
url: http://sametmax.com/quand-ne-pas-utiliser-python/
content:
<p>J&#8217;ai lu récemment sur un forum la question &#8220;quand utiliser Python ?&#8221;. Mais la vérité c&#8217;est que Python est un langage globalement bon partout. En fait, <a href="http://sametmax.com/quest-ce-quon-peut-faire-avec-python/">on peut presque tout faire en Python</a> car c&#8217;est un langage <a href="http://sametmax.com/10-raisons-pour-lesquelles-je-suis-toujours-marie-a-python/">bourré de qualités</a> avec <a href="http://pyvideo.org/">une belle communauté</a> et <a href="http://sametmax.com/tres-grand-listing-des-libs-tierce-partie-les-plus-utiles-en-python/">des libs pour presque tout</a>.</p>
<p>Du coup, je pense qu&#8217;il est plus judicieux de se poser la question inverse : quand ne pas utiliser Python ?</p>
<p>Pour le moment, j&#8217;évite d&#8217;utiliser Python dans les cas suivants :</p>
<ul>
<li>L&#8217;équipe avec laquelle je travaille est bien meilleure dans un autre langage. Il faut profiter des compétences de chacun au maximum plutôt que privilégier une technologie, c&#8217;est plus productif.</li>
<li>Je reprends du code d&#8217;un projet solide, dans un autre langage. Inutile de réécrire quelque chose qui est propre et qui fonctionne.</li>
<li>Je travaille dans un environnement où d&#8217;autres technologies sont mieux intégrées. Par exemple, dans une entreprise avec une forte culture Java, faire les choses dans son coin ne va pas permettre un bon travail d&#8217;équipe. Travailler avec une boîte qui a des serveurs qu&#8217;ils ne peuvent pas changer et d&#8217;autres technos ? Inutile de forcer la main.</li>
<li>Des technologies plus productives existent pour ce domaine : c&#8217;est le cas de l&#8217;embarqué, ou des jeux vidéos. Ça ne veut pas dire qu&#8217;on ne peut pas en faire en Python. En fait, il y a un fort travail de la communauté pour améliorer cela en ce moment même. Mais difficile de combattre les outils en C/C++ dans ces domaines.</li>
<li>Je suis pressé, et la solution de facto n&#8217;est pas en Python. Par exemple, je veux faire du Web temps réel. Si j&#8217;ai le temps, je ferai du Python, car ce n&#8217;est pas grave si il me faut aiguiser moi-même quelques outils pour obtenir le résultat désiré. Si par contre j&#8217;ai 2 semaines devant moi, je prendrais NodeJS, malgré <a href="http://sametmax.com/un-gros-troll-de-plus-sur-javacscript/">mon dégoût pour le Javascript</a>, car je suis pragmatique. </li>
<li>J&#8217;ai <strong>mesuré</strong> mes besoins objectivement, et est évalué que Python ne serait pas assez performant malgré toute les mesures d&#8217;optimisation que je sais mettre en œuvre. Dans ce cas, on se tourne vers des solutions plus lourdes mais nativement plus rapides : C, GO, Erlang etc.</li>
<li>Je vise une plateforme en particulier (Windows, iOS&#8230;), je n&#8217;ai pas besoin de porter mon code, et je sais qu&#8217;utiliser les outils de la boîte qui fait l&#8217;OS me donnera de meilleurs résultats. Par exemple si je vise Android uniquement, utiliser leur SDK donnera une app plus fluide et une UI mieux intégrée.</li>
</ul>
<p>Dans tous les autres cas, Python est un choix excellent.</p>


feed_id: http://sametmax.com/?p=12883
title: Full disclosure 26 Recently updated !
uri: Full-disclosure-Recently-updated
url: http://sametmax.com/full-disclosure/
content:
<p>Depuis quelques jours je suis en discussion avec Tobias de Tavendo. Comme vous avez pu le remarquer avec mes précédents articles sur <a href="http://sametmax.com/crossbar-le-futur-des-applications-web-python/">WAMP</a> et <a href="http://sametmax.com/le-potentiel-de-wamp-autobahn-et-crossbar-io/">Crossbar</a> :</p>
<ul>
<li>Ils sont bons techniquement, et nuls pour expliquer ce qu&#8217;ils ont techniqué.</li>
<li>Cette techno est une techno de rêve pour moi. J&#8217;y crois à mort.</li>
<li>Je suis le seul à avoir pondu des explications décentes sur WAMP et Crossbar. Et ça n&#8217;a pas suffit à faire battre un cil.</li>
</ul>
<p>Bref, ils ont embauché des mecs de haute voltige pour la technique (du genre un contributeur PyPy). Et ils m&#8217;ont contacté pour me demander si je n&#8217;étais pas chaud pour faire de l&#8217;évangélisme, rémunéré, autour de WAMP, Autobahn et Crossbar.</p>
<p>L&#8217;idée : écrire des tutos, des articles, améliorer la doc, répondre sur le chan IRC, etc.</p>
<p>J&#8217;adore le concept, vu que j&#8217;aime leur projet et que je le faisais gratos avant, surtout qu&#8217;ils sont pas trop contraignants sur le temps que je vais passer dessus.</p>
<p>Donc voilà le deal : quand je vais pondre des tutos et des articles sur WAMP et Co, je vais d&#8217;abord les faire en français ici. Comme ça j&#8217;aurai les retours des lecteurs du blog qui pourront, comme d&#8217;habitude, me faire part de leurs douces remarques sur à quel point on ne pige rien.</p>
<p>Une fois la prose aiguisée, je traduis et je publie chez Tavendo.</p>
<p>Je disclose donc ici que vous verrez peut-être des prochaines rédactions qui seront attachées à une activité pro. Pas impartial donc. Mais bon, depuis quand je suis impartial ? Javascript c&#8217;est de la merde, et je préfère les rousses.</p>
<p>Par saucisse d&#8217;honnêteté, je signalerai chaque choucroute concernée avec un lien vers ce post.</p>
<p>Enfin, le contrat est pas signé encore, mais vu que je vais commencer à taffer dessus aujourd&#8217;hui, je pense à une première publication demain sous la forme d&#8217;un slide show expliquant avec de jolies diapos ce que sont WAMP, Autobahn et Crossbar. À quoi ça sert et ce qu&#8217;on peut faire avec.</p>


feed_id: http://sametmax.com/?p=12902
title: Travailler à deux sur iPython à distance 11
uri: Travailler-à-deux-sur-iPython-à-distance
url: http://sametmax.com/travailler-a-deux-sur-ipython-a-distance/
content:
<p>Bon, j&#8217;ai pas fini mon slideshow sur WAMP, donc je vais faire un article sur ça.</p>
<p><a href="http://sametmax.com/profiter-du-notebook-de-ipython/">iPython notebook</a>, c&#8217;est pratique, mais une seule personne peut coder à la fois. Si quelqu&#8217;un veut voir les changements, il faut recharger avec F5. A l&#8217;heure des Google Doc temps réel, c&#8217;est con. Surtout que c&#8217;est du ZMQ derrière.</p>
<p>Du coup je me suis lancé dans une expérimentation avec <a href="https://togetherjs.com/docs/">TogetherJS</a>, la lib de Momo pour le travail collaboratif.</p>
<p>Pour lancer le truc, il suffit d&#8217;aller dans son dossier de profile iPython et éditer le fichier Javascript vierge fait pour étendre l&#8217;outil. Par exemple, sous Ubuntu, mon profile par défaut est dans <code>~/ipython/profile_default</code> et le fichier à éditer est <code>./profile_default/static/custom/custom.js</code>.</p>
<p>Dedans on met :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">TogetherJSConfig_autoStart <span style="color: #66cc66;">=</span> true<span style="color: #66cc66;">;</span>
TogetherJSConfig_cloneClicks <span style="color: #66cc66;">=</span> false<span style="color: #66cc66;">;</span>
TogetherJSConfig_dontShowClicks <span style="color: #66cc66;">=</span> true<span style="color: #66cc66;">;</span>
$.<span style="color: black;">getScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'https://togetherjs.com/togetherjs-min.js'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></pre></td></tr></table></div>

<p>Et on est bon. Il faut ouvrir deux browsers différents pour bien tester le truc, par exemple un chrominou et un firefoune. Moi j&#8217;ai ouvert deux FF parce que j&#8217;ai pleins de profiles dessus.</p>
<p>La frappe est bien synchro, mais malheureusement pas l&#8217;affichage du résultat. Y a donc bien un truc intéressant à creuser, mais pour le moment, c&#8217;est pas utilisable.</p>
<p>Ensuite, il y a des services Web. <a href="https://cloud.sagemath.com/">SageMathCloud</a> annonce faire cela, mais impossible de s&#8217;inscrire, le formulaire ne marche pas. <ahref="https://www.codebox.io">Codebox</ahref=> propose un env complet de dev en ligne, mais l&#8217;inscription est temporairement suspendue. <a href="http://codebunk.com">Codebunk</a> marche pas mal, est plutôt bien foutu et clair, mais Python 2.7 uniquement, et aucun moyen d&#8217;installer une lib, donc adieu scipy ou matplotlib.</p>
<p>Celui qui s&#8217;en rapproche le plus est <a href="https://www.pythonanywhere.com">Pythonanywhere</a> : des consoles synchronisées pour toutes les versions de Python, beaucoup de libs préinstallées (dont scipy et matplotlib), un vrai système de fichier sur lequel travailler, du pip a dispo. Et en prime un éditeur de texte pour des fichiers complets, mais qui lui, n&#8217;est pas collaboratif. Damn it. Et impossible d&#8217;afficher en ligne une image pondue via matplotlib. En plus, on a pas le concept des cellules d&#8217;iPython, qui est super pratique.</p>
<p>Bref, il manque vraiment un outil pour faire ce genre de choses.</p>


feed_id: http://sametmax.com/?p=12923
title: Petit à petit, on reconstruit 24
uri: Petit-à-petit-on-reconstruit-Recently-updated
url: http://sametmax.com/petit-a-petit-on-reconstruit/
content:
<p>Certains l&#8217;auront noté, les tampons sont de retour.</p>
<p>J&#8217;ai aussi, à la demande d&#8217;un lecteur, ajouté un plugin pour permettre aux commentaires d&#8217;être écrits en markdown (avec les extensions de github).</p>
<p>Pour obtenir la parité avec le précédent blog, il nous faudra donc restaurer encore quelques easter eggs et améliorer les images sur la page d&#8217;accueil, mais c&#8217;est presque fini. Comme quoi, une migration, c&#8217;est long. Et chiant. Et ingrat.</p>


feed_id: http://sametmax.com/?p=12939
title: Mieux que Python virtualenvwrapper : pew 8 Recently updated !
uri: Mieux-que-Python-virtualenvwrapper-pew-Recently-updated
url: http://sametmax.com/mieux-que-python-virtualenvwrapper-pew/
content:
<p>Vous avez compris que Python sans <a href="http://sametmax.com/les-environnement-virtuels-python-virtualenv-et-virtualenvwrapper/">virtualenv</a> c&#8217;est comme la mer sans les vagues, c&#8217;est comme les vagues sans l&#8217;écume, c&#8217;est comme l&#8217;écume sans le sel, c&#8217;est comme le sel sans le poivre&#8230;</p>
<p>Mais c&#8217;est aussi appétissant que les méduses échouées.</p>
<p>Donc pour se faciliter la vie, vous utilisez virtualenvwrapper.</p>
<p>Et bien il y a plus meilleur : <a href="https://github.com/berdario/pew#usage">pew</a>.</p>
<p>Non content d&#8217;avoir un nom cool et court, c&#8217;est un progrès non négligeable dans l&#8217;ergonomie de notre vie de dresseur de reptiles.</p>
<p>D&#8217;abord : <code><a href="http://sametmax.com/votre-python-aime-les-pip/">pip</a> install pew</code>.</p>
<p>Ensuite, tableau d&#8217;équivalence avec virtualenvwrapper :</p>
<table class="tableizer-table">
<tbody>
<tr class="tableizer-firstrow">
<th></th>
<th>virtualenvwrapper</th>
<th>pew</th>
</tr>
<tr>
<td>Lister les env existant</td>
<td>workon</td>
<td>pew ls</td>
</tr>
<tr>
<td>Créer un env</td>
<td>mkvirtualenv name</td>
<td>pew new name</td>
</tr>
<tr>
<td>Supprimer un env</td>
<td>rmvirtualenv name</td>
<td>pew rm name</td>
</tr>
<tr>
<td>Activer un env</td>
<td>workon name</td>
<td>pew workon name</td>
</tr>
<tr>
<td>Aller dans le dossier site-packages</td>
<td>cdsitepackages</td>
<td>cd $(pew sitepackages_dir)</td>
</tr>
<tr>
<td>Valeur par défaut pour $WORKON_HOME (dossier qui contient tous les envs)</td>
<td>~/.virtualenvs</td>
<td>~/local/share/virtualenvs</td>
</tr>
</tbody>
</table>
<p>Vous noterez que les commandes de pew sont plus faciles à retenir, plus cohérentes, et toutes des sous-commandes histoire d&#8217;éviter de pourrir son espace de nom.</p>
<p>Autres avantages : pew n&#8217;a pas besoin qu&#8217;on ajoute un fichier à votre <code>.bashrc</code> pour marcher. Car pew ne source pas un env dans votre shell courant, il ouvre un nouveau shell. Pour sortir de l&#8217;env, c&#8217;est donc un simple <kbd>Ctrl</kbd> + <kbd>D</kbd>.</p>
<p>Seulement ça ne s&#8217;arrête pas là. Pew possède quelques commandes bonus qui changent bien la vie :</p>
<table class="tableizer-table">
<tbody>
<tr class="tableizer-firstrow">
<th></th>
<th>virtualenvwrapper</th>
<th>pew</th>
</tr>
<tr>
<td>Éxecuter la commande dans un env sans l&#8217;activer</td>
<td>Nope</td>
<td>pew in name commande</td>
</tr>
<tr>
<td>Éxecuter la commande dans tous les env</td>
<td>Non</td>
<td>pew inall commande</td>
</tr>
<tr>
<td>Dupliquer un virtualenv ailleurs</td>
<td>Nada</td>
<td>pew cp name destination</td>
</tr>
<tr>
<td>Ajouter un chemin au PYTHONPATH de l&#8217;env</td>
<td>Fuck it</td>
<td>pew add path</td>
</tr>
<tr>
<td>Changer la prise en compte des libs du site-packages du système quand on veut</td>
<td>I&#8217;m out</td>
<td>pew toggleglobalsitepackages</td>
</tr>
<tr>
<td>Créer un env temporaire supprimé dès qu&#8217;on en sort</td>
<td>Now you are just pushing it</td>
<td>pew mktmpenv</td>
</tr>
<tr>
<td>Choisir un dossier vers lequel aller à l&#8217;activation de l&#8217;env</td>
<td>BANG !</td>
<td>pew setproject path</td>
</tr>
</tbody>
</table>
<p>Bon, le seul truc qui manque pour le moment, ce sont les hooks.</p>


feed_id: http://sametmax.com/?p=12948
title: Message de service aux débutants en Python 24
uri: Message-de-service-aux-débutants-en-Python-Recently-updated
url: http://sametmax.com/message-de-service-aux-debutants-en-python/
content:
<p>Ces informations sont éparpillées sur le net, et même sur le blog. Mais c&#8217;est un peu le package que tout dev Python qui se lance doit apprendre petit à petit. Alors je vais vous épargner les recherches.</p>
<p>Ne prenez pas ça comme une checklist qu&#8217;il faut impérativement faire avant de programmer. Coder est le plus important pour apprendre. Tout le reste est facultatif. Mais cet article liste des raccourcis qui vous seront utiles au fur et à mesure de votre progression.</p>
<h2>Réponse aux grandes questions de la vie</h2>
<h3>J&#8217;installe Python avec quoi ?</h3>
<p>Sous Linux, avec votre gestionnaire de paquet. Mais souvenez-vous que la 2.7 est installée par défaut.</p>
<p>Sous Mac, avec <a href="http://brew.sh/">homebrew</a>. Mais souvenez-vous que la 2.7 est installée par défaut. Vous aurez besoin de GCC. Mais pas besoin de télécharger xcode pour ça, il y a des <a href="https://github.com/kennethreitz/osx-gcc-installer">solutions légères</a>.</p>
<p>Sous Windows, utilisez <a href="http://conda.pydata.org/miniconda.html">miniconda</a>. L&#8217;installeur officiel est pas mal, mais miniconda vous aidera beaucoup pour plein de choses, comme installer facilement les extensions compilées type scipy ou QT. Et cochez toujours l&#8217;option pour ajouter Python au SYSTEM PATH, sinon il faudra <a href="http://sametmax.com/ajouter-un-chemin-a-la-variable-denvironnement-path-sous-windows/">le faire à la main</a> et c&#8217;est relou.</p>
<h3>Python 2 or Python 3 ?</h3>
<p>Python 3 sauf si :</p>
<ul>
<li>Vous êtes certain de devoir utiliser une lib en rouge dans <a href="https://python3wos.appspot.com/">cette liste</a>.</li>
<li>Vous êtes sur Mac ou Linux, et vous avez pas envie de vous faire chier à installer Python 3 alors que Python 2.7 est déjà là par défaut.</li>
<li>Vous n&#8217;avez pas accès à Python 3.3 ou 3.4. Les premières versions de Python 3 sont horribles.</li>
</ul>
<p>Dans tous les cas, souvenez-vous :</p>
<ul>
<li>Qu&#8217;on peut installer plusieurs versions en même temps.</li>
<li>Que passer de l&#8217;un à l&#8217;autre n&#8217;est pas difficile. On peut même écrire du code compatible avec les deux si besoin même si c&#8217;est un peu chiant.</li>
<li>La commande <code>py</code> permet de choisir quel Python lancer sous Windows (<code>py -2 </code>ou <code>py -3</code>). Sous linux, on peut carrément faire <code>python2</code> ou <code>python3</code>, ou <code>python3.4</code>.</li>
<li>Les environnement virtuels peuvent utiliser une version de Python en particulier avec <code>-p.</code></li>
</ul>
<h3>Mais c&#8217;est quoi cette histoire de CPython, Pypy, IronPython, Jython, Julia, Cython, Nuitka, Hope&#8230;</h3>
<p>Y a combien de Python bordel ?</p>
<p>Pour vous, un seul : CPython. C&#8217;est-à-dire ce que les gens appellent &#8220;Python&#8221;.</p>
<p>Vous pouvez ignorer le reste. Vous n&#8217;avez pas à vous inquiéter de devoir utiliser un autre un jour, devoir passer à un autre, etc. Ce sont juste des bonus qui peuvent aider des gens dans des cas particuliers, rien d&#8217;indispensable.</p>
<h3>Pip ou easy_install</h3>
<p>pip. <a href="http://sametmax.com/votre-python-aime-les-pip/">Installez toujours pip</a>. Utilisez toujours pip. Apprenez à bien utiliser pip avec toutes ses options.</p>
<p>Et souvenez-vous qu&#8217;on peut installer un module pour une version de python en particulier en faisant <code>pythonX -m pip</code> ou sous windows, <code>py -x -m pip</code>.</p>
<p>Une exception pour les extensions :</p>
<p>Si vous êtes sous Windows, installer <strong>en plus</strong> miniconda va vous simplifier énormément la vie pour installer les extensions compilées comme scipy.</p>
<p>Et si vous êtes sous Linux utilisez votre gestionnaire de paquet sans quoi vous allez devoir installer gcc et les headers de Python (package python-dev sous Ubuntu par exemple).</p>
<h3>distutils, setuptools ou distribute ?</h3>
<p>Setuptools. Le reste a été fusionné ou déprécié.</p>
<h3>Python 32 bits ou python 64 bits ?</h3>
<p>64 bits. Si vous avez un jour une erreur indébuggable sous windows, testez avec une version 32 bits au cas où. Mais 64 bits reste le choix par défaut.</p>
<h3>Quel IDE ?</h3>
<p>Aucun IDE n&#8217;est nécessaire en Python. On peut coder avec un simple éditeur de texte et la console. Je fais toutes mes formations avec Notepad++ sous Windows, ou Gedit sous Ubuntu.</p>
<p>Vous pouvez donc juste utiliser ce que vous aimez le plus.</p>
<h3>Pour UI, PyQt, PySide, wxPython, Kivy, PyGTK, Tkinter ?</h3>
<p><a href="https://docs.python.org/2/library/tkinter.html">Tkinter</a> si c&#8217;est une UI simple (quelques fenêtres, quelques formulaires). <a href="http://wxpython.org/">WxPython</a> si c&#8217;est un programme complexe en Python 2.7. C&#8217;est le meilleur équilibre poids/puissance. <a href="http://kivy.org/">Kivy</a> si ça doit tourner sur mobile.</p>
<p><a href="http://www.riverbankcomputing.co.uk/software/pyqt/intro">PyQt</a>/<a href="http://qt-project.org/wiki/PySide">PySide</a> sont les plus puissants, mais beaucoup plus dur à utiliser. Ca vaut rarement le coup, sauf que pour le moment, c&#8217;est la seule solution solide en Python 3.</p>
<h2>Les outils qui changent la vie</h2>
<p>On peut coder avec Python sans tout ça, mais la vie est plus belle avec.</p>
<ul>
<li>pip permet d&#8217;installer facilement plein de libs.</li>
<li><a href="http://ipython.org/">ipython</a>, un shell Python qui facilite l&#8217;expérimentation de code.</li>
<li><a href="http://sametmax.com/debugger-en-python-les-bases-de-pdb/">pdb</a> permet de débugger votre programme. <a href="https://pypi.python.org/pypi/pdbpp/">pdb++</a> en bonus.</li>
<li><a href="http://sametmax.com/les-environnement-virtuels-python-virtualenv-et-virtualenvwrapper/">virtualenv</a> vous permet d&#8217;avoir des installations de Python différentes pour chaque projet avec des libs isolées. Avec <a href="http://sametmax.com/mieux-que-python-virtualenvwrapper-pew/">pew</a> en bonus.</li>
<li><a href="http://sametmax.com/grin-le-grep-python-sous-steroid/">grin</a>, pour rechercher un mot dans votre code. Mieux que grep et marche sous Windows.</li>
<li><a href="http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/">pyped</a>, pour remplacer sed, cut, awk et bien plus par du python simple, y compris sous Windows</li>
</ul>
<p>Si vous êtes sous windows, souvenez-vous que <kbd>Shift</kbd> avant un clic droit ajoute des options supplémentaires au menu contextuel de votre explorateur de fichiers. Avec notamment &#8220;Ouvrir une invite de commande dans ce dossier&#8221;. Sous Mac il y a un <a href="http://hdrapin.com/2013/02/17/mac-comment-ouvrir-le-dossier-selectionne-dans-le-terminal/">réglage</a> pour ça. <a href="http://www.distrogeeks.com/open-terminal-here-ubuntu/">Sous Ubuntu il y a un plugin</a>.</p>
<p>Ah oui, et sous windows, utilisez <a href="https://github.com/cbucher/console/wiki/Downloads">une console décente</a>.</p>
<h2>Bonnes habitudes</h2>
<p>Réglez votre éditeur de texte pour utiliser 4 espaces pour indenter. Si vous préférez les tabs, réglez aussi votre éditeur de texte pour utiliser 4 espaces pour indenter.</p>
<p>Tant qu&#8217;on y est, <a href="http://sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/">apprenez à gérer votre encoding</a>. Particulièrement, assurez-vous de savoir où changer l&#8217;encoding des caractères de vos fichiers dans les options de votre éditeur de texte. Et mettez le par défaut sur UTF8. Utilisez toujours des chaînes de caractères unicode et le header <code># -*- coding: utf-8 -*-</code>.</p>
<p>Utilisez <code>print</code> avec la syntaxe sous forme de fonction. Et faites des imports absolus, jamais relatifs.</p>
<p>En fait, si vous êtes en Python 2.7, activez le plus de comportement de Python 3 possible en faisant les imports de <code>__future__</code>.</p>
<p>Pour un débutant, voici donc un bon template de fichier Python 2.7 par défaut :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;
    Documenter le module ici.
&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">__future__</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: black;">&#40;</span>unicode_literals<span style="color: #66cc66;">,</span> absolute_import<span style="color: #66cc66;">,</span>
                        print_function<span style="color: #66cc66;">,</span> division<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Run the whole program &quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># votre code ici</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Hello !'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<ul>
<li><strong>unicode_literals</strong> : active les chaînes unicode par défaut.</li>
<li><strong>absolute_import</strong> : active les imports absolus par défaut.</li>
<li><strong>print_function</strong> : remplace le mot clé <strong>print</strong> par la fonction <strong>print()</strong>.</li>
<li><strong>division</strong> : <code>/</code> devient la division classique, <code>//</code> la division entière.</li>
</ul>
<p>Pour Python 3, c&#8217;est plus simple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">&quot;&quot;&quot;
    Documenter le module ici.
&quot;&quot;&quot;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot; Run the whole program &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Hello !'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Utilisez toujours des dates en UTC. Ne convertissez qu&#8217;à l&#8217;affichage. Donc ça veut dire utiliser <code>datetime.utcnow()</code> et non <code>datetime.now()</code></p>
<h2>Des libs qu&#8217;on les aime</h2>
<p>Les modules disponibles avec Python sont ce qu&#8217;on appelle la bibliothèque standard, ou stdlib. Il y a beaucoup de modules <a href="http://sametmax.com/tres-grand-listing-des-libs-standard-partie-les-plus-utiles-en-python/">très utiles</a>.</p>
<p>Néanmoins certains doivent avoir la priorité dans votre apprentissage. Les plus importants sont :</p>
<ul>
<li><a href="https://docs.python.org/2/library/os.html?highlight=os#module-os">os</a>, <a href="https://docs.python.org/2/library/shutil.html?highlight=shutils">shutil</a>, <a href="https://docs.python.org/2/library/subprocess.html?highlight=subprocess">subprocess</a> et <a href="https://docs.python.org/2/library/sys.html?highlight=sys#module-sys">sys</a> : manipuler votre OS, des fichiers aux processus.</li>
<li><a href="https://docs.python.org/2/library/datetime.html?highlight=datetime#module-datetime">datetime</a> : manipuler les dates.</li>
<li><a href="https://docs.python.org/2/library/math.html?highlight=math#module-math">math</a> et <a href="https://docs.python.org/2/library/decimal.html?highlight=decimal#module-decimal">decimal</a> : ben, les maths.</li>
<li><a href="https://docs.python.org/2/library/collections.html?highlight=collection#module-collections">collections</a> : des structures de données avancées.</li>
<li><a href="https://docs.python.org/2/library/decimal.html?highlight=decimal#module-decimal">argparse</a> : faire un script avec des paramètres.</li>
<li><a href="https://docs.python.org/2/library/urllib2.html?highlight=urllib#module-urllib2">urllib2</a> : faire des requêtes HTTP.</li>
<li><a href="https://docs.python.org/2/library/itertools.html?highlight=itertools#module-itertools">itertools</a> : l&#8217;itération est tout en Python.</li>
</ul>
<p>Quelques modules sont vieux, et ça se sent dans leur facilité d&#8217;usage. Pour cette raison, si vous utilisez beaucoup certains d&#8217;entre eux, des alternatives installables avec pip peuvent vous simplifier <strong>énormément</strong> la vie :</p>
<table class="tableizer-table">
<tbody>
<tr>
<td>Stdlib</td>
<td>Lib tierce partie plus pratique&gt;</td>
</tr>
<tr class="tableizer-firstrow">
<td>datetime</td>
<td><a href="http://sametmax.com/les-time-zones-en-python/">arrow</a></td>
</tr>
<tr>
<td>os, sys, shutil</td>
<td><a href="http://sametmax.com/path-py-plus-en-detail/">path.py</a></td>
</tr>
<tr>
<td>argparse</td>
<td><a href="http://sametmax.com/la-plus-belle-maniere-de-parser-les-arguments-de-script-en-python/">docopt</a></td>
</tr>
<tr>
<td>unittest</td>
<td><a href="http://sametmax.com/se-simplifier-les-tests-python-avec-pytest/">pytest</a>. En fait ne faites jamais de <a href="http://sametmax.com/un-gros-guide-bien-gras-sur-les-tests-unitaires-en-python-partie-1/">tests unitaires</a> sans pytest. La vie est trop courte.</td>
</tr>
<tr>
<td>urllib2</td>
<td><a href="http://docs.python-requests.org/en/latest/">requests</a></td>
</tr>
</tbody>
</table>
<h2>Y a des priorités dans la vie</h2>
<p>Les trucs importants à apprendre en Python (qui sont typiques de ce langage, j&#8217;entends) avant de se lancer dans la sophistication :</p>
<ul>
<li>Toutes les choses ont une valeur booléenne. Savoir en tirer parti.</li>
<li>Connaitre toutes les méthodes des strings.</li>
<li>Les exceptions : try, except, else, finally, raise.</li>
<li>Maitriser le slicing et l&#8217;unpacking.</li>
<li><a href="http://sametmax.com/operateur-splat-ou-etoile-en-python/">L&#8217;opérateur splat</a>.</li>
<li>Manipuler des fichiers.</li>
<li>Les dictionnaires et les sets. Vous les sous-utilisez. Étudiez-les.</li>
<li>Bien maitriser l&#8217;itération : for, else, continue, break.</li>
<li>Bien maitriser l&#8217;itération (bis) : zip, enumerate, sorted, reversed, any, all&#8230;</li>
<li>Bien maitriser l&#8217;itération (ter) : <a href="http://sametmax.com/python-love-les-listes-en-intention-partie/">les listes en intension</a>.</li>
<li>Bien maitriser l&#8217;itération (vous-ai je dit que c&#8217;était tout en Python ?) : <a href="http://sametmax.com/comment-utiliser-yield-et-les-generateurs-en-python/">les générateurs</a>.</li>
<li>Les regex. C&#8217;est chiant. Je sais. Mais c&#8217;est trop puissant pour être ignoré.</li>
</ul>
<p>Avec ça vous pouvez aborder sereinement tout problème. Le reste, c&#8217;est du bonus.</p>
<p>Typiquement, on peut repousser à bien plus tard l&#8217;apprentissage de :</p>
<ul>
<li><a href="http://sametmax.com/fonctions-anonymes-en-python-ou-lambda/">Les lambdas</a>.</li>
<li><a href="http://sametmax.com/comprendre-les-decorateurs-python-pas-a-pas-partie-1/">Decorateurs</a>.</li>
<li>Les <a href="http://sametmax.com/les-context-managers-et-le-mot-cle-with-en-python/">context managers</a>.</li>
<li>L&#8217;introspection.</li>
<li><a href="http://sametmax.com/le-guide-ultime-et-definitif-sur-la-programmation-orientee-objet-en-python-a-lusage-des-debutants-qui-sont-rassures-par-les-textes-detailles-qui-prennent-le-temps-de-tout-expliquer-partie-1/">La programmation orientée objet</a>.</li>
<li>Metaclasses.</li>
</ul>


feed_id: http://sametmax.com/?p=12969
title: Présentation de WAMP.ws, round 2 39
uri: Présentation-de-WAMP-ws-round-2-Recently-updated
url: http://sametmax.com/presentation-de-wamp-round-2/
content:
<p>Dans le cadre de <a href="http://sametmax.com/full-disclosure/">mon travail sur WAMP</a>, j&#8217;ai proposé à Tobias de commencer par une présentation générale de la stack techno sous forme de slide show.</p>
<p>L&#8217;idée est de mettre ça dans le header des sites de WAMP, crossbar.io et autobahn, afin que quand les gens arrivent dessus ils puissent rapidement voir de quoi on parle. Ou alors, si on est sur un forum, on peut linker vers les diapos pour donner un contexte.</p>
<p><iframe src="https://www.slideshare.net/slideshow/embed_code/42901476" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/sametmax/introduction-wampws-le-protocole-websocket-pour-faire-du-pubsub-et-rpc-over-websocket-en-tempr" title="Présentation de WAMP.ws, le protocole pour faire du PUB/SUB et RPC over Websocket" target="_blank">Présentation de WAMP.ws, le protocole pour faire du PUB/SUB et RPC over Websocket</a> </strong> from <strong><a href="http://www.slideshare.net/sametmax" target="_blank">sametmax</a></strong> </div>
<p>Comme prévu, je fais une première version en français que je poste ici. Puis je vais récolter vos commentaires : qu&#8217;est-ce qu&#8217;on comprend pas, quelles informations manquent, qu&#8217;est-ce qui est flou, ambigüe, etc.</p>
<p>Ensuite je l&#8217;améliorerai lors de la traduction en anglais qui sera ensuite proposée à Tavendo.</p>


feed_id: http://sametmax.com/?p=12995
title: Embarquement en porte 19 3
uri: Embarquement-en-porte-19
url: http://sametmax.com/embarquement-en-porte-19/
content:
<p>Bon, je vais rejoindre Max et j&#8217;ai 12 heures de vol et 13 heures d&#8217;escale, donc je ferai les fixes sur les slides durant le vol. Ca me donne plus de temps pour le reste. Pas d&#8217;amélioration aujourd&#8217;hui donc. Mais merci beaucoup à tous les retours, ils sont vraiment très utiles. </p>
<p>Un de ces 4 faudra que je fasse un article sur les tests ergonomiques, ça marche un peu pareil :)</p>


feed_id: http://sametmax.com/?p=13004
title: Les trucmuchables en Python 9 Recently updated !
uri: Les-trucmuchables-en-Python-Recently-updated
url: http://sametmax.com/les-trucmuchables-en-python/
content:
<p>Parcourez votre itérable, passez un callable, retournez un indexable&#8230;</p>
<p>En Python on aime le duck typing. On ne va donc pas s&#8217;intéresser à un type, mais à un comportement.</p>
<p>Quand vous voyez un suffixe &#8220;-able&#8221; en anglais, ça veut dire &#8220;accepte qu&#8217;on lui fasse quelque chose&#8221;. Par exemple, &#8220;fuckable&#8221; = &#8220;baisable&#8221;.</p>
<p>Sur ce morceau de poésie, je vous offre un peu de Vivaldi pour faire glisser profondément ce gros article qui va lister les chosables les plus connus.</p>
<p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/watQ28Fx2Mg?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p>
<h2>Iterable</h2>
<p>Le plus important en Python.</p>
<p>Un itérable est ce qui accepte l&#8217;itération, ce sur quoi on peut itérer, c&#8217;est à dire une collection dont on peut prendre les éléments un à un.</p>
<p>Pour faire simple, <strong>tout ce sur quoi on peut appliquer une boucle <code>for</code></strong>.</p>
<p>L&#8217;exemple le plus connu sont les listes :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'une'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'liste'</span><span style="color: black;">&#93;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
une
liste</pre></td></tr></table></div>

<p>Mais cela s&#8217;applique à bien d&#8217;autres types :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #483d8b;">'unechaine'</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
...
<span style="color: black;">u</span>
n
e
c
h
a
i
n
e
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'un'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'tuple'</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
...
<span style="color: black;">un</span>
<span style="color: #008000;">tuple</span>
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'un'</span>: <span style="color: #483d8b;">'dico'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'par'</span>: <span style="color: #483d8b;">'cle'</span><span style="color: black;">&#125;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
...
<span style="color: black;">un</span>
par
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'un'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'set'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
...
<span style="color: black;">un</span>
<span style="color: #008000;">set</span>
<span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/test'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'un<span style="color: #000099; font-weight: bold;">\n</span>fichier'</span><span style="color: black;">&#41;</span>
...
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/test'</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span> end<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
...
<span style="color: black;">un</span>
fichier</pre></td></tr></table></div>

<p>Les tuples, dicos, sets, fichiers, et strings sont itérables. Beaucoup de structures de données du module <a href="http://sametmax.com/ce-que-vous-ne-saviez-pas-sur-les-collections-en-python/">collections</a> (<code>deque</code>, <code>namedtupple</code>, <code>defaultdict</code>) sont itérables.</p>
<p>Mais surtout, les générateurs sont itérables :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> generator<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #ff4500;">2</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> generator<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">2</span></pre></td></tr></table></div>

<p>Pour vérifier si quelque chose est itérable, on peut utiliser la fonction <code>iter()</code>. Cette fonction prend un iteérable, et retourne un générateur (appelé &#8220;iterator&#8221;) qui permet d&#8217;énumérer chaque élément de l&#8217;iterable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">lst <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'ceci'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'est'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'aussi'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'une'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'liste'</span><span style="color: black;">&#93;</span>
generateur <span style="color: #66cc66;">=</span> <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span>lst<span style="color: black;">&#41;</span>
next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'ceci'</span>
next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'est'</span>
next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'aussi'</span>
next<span style="color: black;">&#40;</span>generateur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'une'</span></pre></td></tr></table></div>

<p><code>iter()</code> lève <code>TypeError</code> sur un non iterable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: <span style="color: #483d8b;">'int'</span> <span style="color: #008000;">object</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> iterable</pre></td></tr></table></div>

<p>Pour la culture, c&#8217;est ainsi que la boucle <code>for</code> fonctionne : à coup de <code>next()</code> sur un itérateur.</p>
<p>On peut rendre n&#8217;importe quelle objet itérable en définissant la méthode <code>__iter__</code>, qui doit retourner un générateur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> NouvelIterable:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__iter__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># mettre des yield marche aussi</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> NouvelIterable<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">2</span>
<span style="color: #ff4500;">3</span></pre></td></tr></table></div>

<p>Les itérables sont les bidulables les plus important en Python car de très nombreuses fonctions les acceptent :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'AZERTY'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># tri</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'A'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'E'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'R'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'T'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Y'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Z'</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'AZERTY'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># inversion</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Y'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'T'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'R'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'E'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Z'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'A'</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">zip</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'AZERTY'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">300</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">600</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># lier deux itérables</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'A'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Z'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'E'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">600</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">any</span><span style="color: black;">&#40;</span><span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># un élément au moins est vrai ?</span>
<span style="color: #008000;">True</span>
<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># tous les éléments sont vrais ?</span>
<span style="color: black;">&#41;</span>
<span style="color: #008000;">False</span></pre></td></tr></table></div>

<p>Et elles retournent souvent des itérables également :)</p>
<p>La plupart des itérables sont compatibles entre eux. Y compris les générateurs. Qui souvent traitent eux même des itérables et retournent des itérables. Cela permet de faire d&#8217;énormes pipelines de traitements connectés les uns aux autres :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">s <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'123456789'</span>
res <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> * x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> s<span style="color: black;">&#41;</span>
<span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: #008000;">reversed</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#40;</span>res<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'999999999'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'88888888'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'7777777'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'666666'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<h2>Mutable</h2>
<p>Dont on peut changer la valeur.</p>
<p>Quand on assigne une variable en Python, on ne change pas la valeur de l&#8217;objet, on change la valeur de la variable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">a <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
a <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span></pre></td></tr></table></div>

<p>Ici <code>1</code> n&#8217;a pas changé, la valeur stockée dans <code>a</code> a changé.</p>
<p>C&#8217;est différent de ceci :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">a <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
a<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span>
a
<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Ici, c&#8217;est la même liste qui est dans <code>a</code>, mais la valeur stockée dans la liste a changé.</p>
<p>Cette notion est importante car en Python, les variables ne contiennent en fait pas vraiment des valeurs, mais des références à ces valeurs.</p>
<p>Si je change le contenu de la variable, il n&#8217;y a pas d&#8217;effet de bords :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">a <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
b <span style="color: #66cc66;">=</span> a <span style="color: #808080; font-style: italic;"># b et a contienne une référence à la même liste</span>
b
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
a <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># le contenu de a change</span>
b
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># b et a ont une contenu différents</span></pre></td></tr></table></div>

<p>Si je change la valeur de ma structure de données, ici ma liste, alors il y a un effet de bord :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">a <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
b <span style="color: #66cc66;">=</span> a
a<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1000</span>
b <span style="color: #808080; font-style: italic;"># a et b référencent la même liste</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1000</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>En effet, <code>a</code> ne contient pas la liste, mais une référence à la liste. Quand on copie le contenu de <code>a</code> vers <code>b</code>, on ne copie pas la liste, mais cette référence. Donc <code>a</code> et <code>b</code> sont des variables qui pointent vers <strong>la même liste</strong>.</p>
<p>Il est alors important de savoir quelles opérations modifient quelque chose, et lesquelles ne les modifient pas.</p>
<p>Les listes, les dictionnaires et les sets sont modifiables, on dit qu&#8217;il sont &#8220;mutables&#8221;.</p>
<p>On peut le voir avec la fonction <code>id()</code> qui renvoie le numéro unique de l&#8217;objet :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">une_liste <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">id</span><span style="color: black;">&#40;</span>une_liste<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">140693805855368</span>
une_liste.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
une_liste
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">id</span><span style="color: black;">&#40;</span>une_liste<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">140693805855368</span></pre></td></tr></table></div>

<p>La liste a changé, mais l&#8217;id est le même, c&#8217;est le même objet.</p>
<p>Les opérations qui &#8220;changent la valeur&#8221; sur les types mutables sont performantes en Python car il n&#8217;y a pas besoin de recréer un objet à chaque fois.</p>
<p>Les tuples, les nombres, les chaînes de caractères ne sont pas modifiables. Il ne sont pas &#8220;mutables&#8221; :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">id</span><span style="color: black;">&#40;</span>une_liste<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">140693805855368</span>
un_tuple <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">id</span><span style="color: black;">&#40;</span>un_tuple<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">140693772746040</span>
un_tuple +<span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
un_tuple
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">id</span><span style="color: black;">&#40;</span>un_tuple<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">140693772879144</span></pre></td></tr></table></div>

<p>Le tuple n&#8217;a pas changé : l&#8217;id n&#8217;est pas le même car la variable <code>un_tuple</code> contient un nouvel objet.</p>
<p>Les opérations qui &#8220;changent la valeur&#8221; sur les types non mutables sont moins performantes en Python car il faut recréer un objet à chaque fois.</p>
<p>Par défaut, toute classe que vous écrivez crée un objet mutable.</p>
<h2>Callable</h2>
<p>Tout ce qui peut être appelé, c&#8217;est à dire qu&#8217;on peut mettre <code>()</code> après le nom de la variable qui le contient pour obtenir un effet.</p>
<p>Ce qui vient en premier en tête ce sont les fonctions (ou les méthodes):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Je suis appelée&quot;</span><span style="color: black;">&#41;</span>
...
<span style="color: black;">foo</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># j'appelle ma fonction</span>
Je suis appelée</pre></td></tr></table></div>

<p>Mais, en Python, le concept d&#8217;appeler va plus loin.</p>
<p>Une classe est un callable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Bar:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Je suis appelée&quot;</span><span style="color: black;">&#41;</span>
Bar<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># j'instancie en utilisant ()</span>
&nbsp;
Je suis appelée</pre></td></tr></table></div>

<p>Un type est un callable :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Et on peut rendre n&#8217;importe quel objet callable en définissant la méthode <code>__call__</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> UnCallableQuiCreerUnCallable:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__call__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Je suis appelé'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">callable</span> <span style="color: #66cc66;">=</span> UnCallableQuiCreerUnCallable<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">callable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Je suis appelé</pre></td></tr></table></div>

<p>Donc quand on vous dit : &#8220;ceci attend un callable en paramètre&#8221;, vous pouvez passer n&#8217;importe quel type de callable. Pas juste une fonction. On peut créer des décorateurs avec et pour n&#8217;importe quel callable.</p>
<p>Si on essaye d&#8217;appeler un objet qui n&#8217;est pas un callabe, on obtient un <code>TypeError</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">lst
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
lst<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    lst<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: <span style="color: #483d8b;">'list'</span> <span style="color: #008000;">object</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">callable</span></pre></td></tr></table></div>

<h2>Hashable</h2>
<p>Les clés des dictionnaires n&#8217;ont pas besoin d&#8217;être des chaînes de caractères. Elles peuvent être n&#8217;importe quel objet hashable. Pour les types de base, ce sont les non mutables, soit les strings, mais aussi ints, floats ou tuples :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">dico <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'une'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'cle'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'qui'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'est'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'un'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'tuple'</span><span style="color: black;">&#41;</span>: <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span>
<span style="color: #008000;">len</span><span style="color: black;">&#40;</span>dico<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
dico<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'une'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'cle'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'qui'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'est'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'un'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'tuple'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
<span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>Pour obtenir cet effet, le dictionnaire prend l&#8217;objet passé en clé, et calcule un hash, une empreinte unique de l&#8217;objet. Pour que cela marche, il faut que le hash d&#8217;un objet donne toujours le même résultat si il est appliqué deux fois au même objet, ou à deux objets parfaitement égaux.</p>
<p>Un objet hashable est donc un objet qu&#8217;on peut utiliser comme clé de dictionnaire. C&#8217;est un objet qu&#8217;on peut passer à la fonction <code>hash()</code>. Dans la stdlib, les types non mutables sont hashable, et les types mutables ne le sont pas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">hash</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fdkslmf&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">4874978338908949266</span>
<span style="color: #008000;">hash</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    <span style="color: #008000;">hash</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: unhashable <span style="color: #008000;">type</span>: <span style="color: #483d8b;">'list'</span></pre></td></tr></table></div>

<p>Mais on peut créer sa propre définition de ce qu&#8217;est un objet hashable avec la méthode <code>__hash__</code>, qui doit retourner un entier :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Personne:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> nom<span style="color: #66cc66;">,</span> prenom<span style="color: #66cc66;">,</span> age<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">nom</span> <span style="color: #66cc66;">=</span> nom
        <span style="color: #008000;">self</span>.<span style="color: black;">prenom</span> <span style="color: #66cc66;">=</span> prenom
        <span style="color: #008000;">self</span>.<span style="color: black;">age</span> <span style="color: #66cc66;">=</span> age
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__hash__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">nom</span> + <span style="color: #008000;">self</span>.<span style="color: black;">prenom</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + <span style="color: #008000;">self</span>.<span style="color: black;">age</span>
...
<span style="color: #008000;">hash</span><span style="color: black;">&#40;</span>Personne<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bob&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;sinclaire&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">78</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1339</span></pre></td></tr></table></div>

<p>Vous avez néanmoins intérêt à savoir ce que vous faites en faisant ça, c&#8217;est un nid de frelons.</p>
<h2>Subscriptables</h2>
<p>Ce dont on peut récupérer une partie avec <code>[]</code>. Essayer sur un objet qui ne l&#8217;est pas peut lever <code>TypeError: 'x' object is not subscriptable</code> ou une sous erreur.</p>
<p>Car on peut utiliser <code>[]</code> de deux façons.</p>
<h3>Indexable</h3>
<p>Dont on peut récupérer un élément à une position particulière, avec la syntaxe <code>[]</code>. Dans la stdlib, les listes, les chaînes de caractères, les tuples et les dictionnaires sont indexables mais pas les sets :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">&quot;fdjskl&quot;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'f'</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'1'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'2'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'1'</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'yo'</span>: <span style="color: #483d8b;">'man'</span><span style="color: black;">&#125;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'yo'</span><span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'man'</span>
s <span style="color: #66cc66;">=</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
s<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    s<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">TypeError</span>: <span style="color: #483d8b;">'set'</span> <span style="color: #008000;">object</span> does <span style="color: #ff7700;font-weight:bold;">not</span> support indexing</pre></td></tr></table></div>

<p>On peut définir son propre comportement d&#8217;indexation avec <code>__getitem__</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> MainGauche:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getitem__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> index<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;Index de la main gauche&quot;</span>
&nbsp;
main <span style="color: #66cc66;">=</span> MainGauche<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>main<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
Index de la main gauche</pre></td></tr></table></div>

<h3>Sliceable</h3>
<p>Dont on peut récupérer un sous ensemble des éléments avec la syntaxe <code>[start:stop:step]</code>. Un sliceable est souvent indexable, mais l&#8217;inverse n&#8217;est pas forcément vrai. Dans la stdlib, les listes, les strings et les tuples sont sliceables, mais pas les dictionnaires ni les sets :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">&quot;fdjskl&quot;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>::<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'dsl'</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'1'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'2'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">False</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'1'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'2'</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'yo'</span>: <span style="color: #483d8b;">'man'</span><span style="color: black;">&#125;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    <span style="color: black;">&#123;</span><span style="color: #483d8b;">'yo'</span>: <span style="color: #483d8b;">'man'</span><span style="color: black;">&#125;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">TypeError</span>: unhashable <span style="color: #008000;">type</span>: <span style="color: #483d8b;">'slice'</span></pre></td></tr></table></div>

<p>Le slice s&#8217;implémente comme l&#8217;index, avec <code>__getitem__</code>. La différence est qu&#8217;au lieu de recevoir une valeur ordinaire, vous allez recevoir un objet slice :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> MainDroite:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getitem__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">slice</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #008000;">slice</span>.<span style="color: black;">start</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">slice</span>.<span style="color: black;">stop</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;Slice de la main droite. Heu...&quot;</span>
&nbsp;
main <span style="color: #66cc66;">=</span> MainDroite<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>main<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span> <span style="color: #ff4500;">6</span>
Slice de la main droite. <span style="color: black;">Heu</span>...</pre></td></tr></table></div>


feed_id: http://sametmax.com/?p=13011
title: Corrections des slides WAMP 8
uri: Corrections-des-slides-WAMP-Recently-updated
url: http://sametmax.com/corrections-des-slides-wamp/
content:
<p>Suite aux commentaires, j&#8217;ai fais une refonte des dispos :</p>
<ul>
<li>Plus d&#8217;insistance sur la différence entre RPC et PUB/SUB.</li>
<li>Les exemples sont amenés plus tôt, et les schémas sont en premier.</li>
<li>Des lourdeurs et des redondances sont supprimées.</li>
<li>J&#8217;ai ajouté des réponses à quelques questions posées : perf, sécu, etc.</li>
</ul>
<p>Histoire d&#8217;éviter d&#8217;éparpiller des versions partout, je l&#8217;ai juste réup <a href="http://sametmax.com/presentation-de-wamp-round-2/">au même endroit</a>.</p>
<p>Merci, donc, pour toutes les remarques qui ont significativement permises d&#8217;améliorer la prez.</p>


feed_id: http://sametmax.com/?p=13019
title: Qu’est-ce que l’unpacking en Python et à quoi ça sert ? 6
uri: Qu-est-ce-que-l-unpacking-en-Python-et-à-quoi-ça-sert-Recen
url: http://sametmax.com/quest-ce-que-lunpacking-en-python-et-a-quoi-ca-sert/
content:
<p>Ce terme apparaît dans de nombreux articles du blog, et je prends parfois le temps de l&#8217;expliquer superficiellement. Évidemment, à de nombreux moments j&#8217;ai fait des tutos en ayant la connaissance de l&#8217;unpacking comme prérequis, et rien vers quoi faire un lien. Corrigeons ça, en attendant que je traduise les slides sur WAMP.</p>
<h2>Le principe de base</h2>
<p>Normalement, si vous voulez mettre le contenu d&#8217;un tuple dans des variables, vous devez procéder ainsi :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> ducks <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'riri'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'fifi'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'loulou'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duck1 <span style="color: #66cc66;">=</span> ducks<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duck2 <span style="color: #66cc66;">=</span> ducks<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duck3 <span style="color: #66cc66;">=</span> ducks<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck1<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'riri'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck2<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'fifi'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck3<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'loulou'</span></pre></td></tr></table></div>

<p>L’unpacking, qu&#8217;on pourrait traduire par le terme fort moche de &#8220;déballage&#8221;, dans le sens &#8220;ouvrir un colis&#8221;, permet de faire la même chose, bien plus facilement :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> duck1<span style="color: #66cc66;">,</span> duck2<span style="color: #66cc66;">,</span> duck3 <span style="color: #66cc66;">=</span>  ducks
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck1<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'riri'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck2<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'fifi'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>duck3<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'loulou'</span></pre></td></tr></table></div>

<p>Il n&#8217;y a rien à faire, c&#8217;est automatique. La seule condition est que le nombre de variables à gauche du signe égal soit le même que le nombre d&#8217;éléments dans la collection de droite.</p>
<p>D&#8217;ailleurs, ça marche même avec un seul élément :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> ducks <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'riri'</span><span style="color: #66cc66;">,</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duck1<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">=</span> ducks <span style="color: #808080; font-style: italic;"># notez la virgule</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duck1
<span style="color: #483d8b;">'riri'</span></pre></td></tr></table></div>

<p>Et ça marche avec n&#8217;importe quel <a href="http://sametmax.com/les-trucmuchables-en-python/">itérable</a>, pas uniquement les tuples. Avec une liste, une string, un générateur&#8230;</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> b<span style="color: #66cc66;">,</span> c<span style="color: #66cc66;">,</span> d <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> c
<span style="color: #ff4500;">3</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> b <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;12&quot;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b
<span style="color: #483d8b;">'2'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> yolo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #483d8b;">&quot;leroy&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #483d8b;">&quot;jenkins&quot;</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> nom<span style="color: #66cc66;">,</span> prenom <span style="color: #66cc66;">=</span> yolo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> nom
<span style="color: #483d8b;">'leroy'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> prenom
<span style="color: #483d8b;">'jenkins'</span></pre></td></tr></table></div>

<p>Ça marche bien entendu avec un dico ou un set, mais comme ils ne sont pas ordonnés, c&#8217;est pas très utile.</p>
<h2>Astuces autour de l&#8217;unpacking</h2>
<p>On peut utiliser l&#8217;unpacking dans des endroits inattendus. Par exemple, pour échanger la valeur de deux variables :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> a <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> b <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>b<span style="color: #66cc66;">,</span> a<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> b <span style="color: #66cc66;">=</span> b<span style="color: #66cc66;">,</span> a <span style="color: #808080; font-style: italic;"># les parenthèses sont facultatives dans les tuples</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b
<span style="color: #ff4500;">2</span></pre></td></tr></table></div>

<p>Puisqu&#8217;on est dans les tuples sans parenthèses, on peut retourner un tuple et donner l&#8217;illusion de retourner plusieurs variables :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> duckmebaby<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;rifi&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'filou'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'louri'</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> et<span style="color: #66cc66;">,</span> hop<span style="color: #66cc66;">,</span> la <span style="color: #66cc66;">=</span> duckmebaby<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> et
<span style="color: #483d8b;">'rifi'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> hop
<span style="color: #483d8b;">'filou'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> la
<span style="color: #483d8b;">'louri'</span></pre></td></tr></table></div>

<p>Allons plus loin.</p>
<p>On peut utiliser l&#8217;unpacking à l&#8217;intérieur d&#8217;une boucle <code>for</code>. Souvenez vous que les itérables peuvent contenir d&#8217;autres itérables. Par exemple, j&#8217;ai une liste qui contient 3 tuples, chaque tuple contient deux éléments :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> scores <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Monique'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'3'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'David'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Dick'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> score <span style="color: #ff7700;font-weight:bold;">in</span> scores:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>score<span style="color: black;">&#41;</span>
...
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Monique'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'3'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'David'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Dick'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Si je veux afficher le nom et le score l&#8217;un en dessous de l&#8217;autre :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> nom_et_score <span style="color: #ff7700;font-weight:bold;">in</span> scores:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nom_et_score<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nom_et_score<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
...
<span style="color: black;">Monique</span>
<span style="color: #ff4500;">3</span>
David
<span style="color: #ff4500;">10</span>
Dick
<span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>Je peux appliquer l&#8217;unpacking dans la boucle pour rendre cette opération plus élégante :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> nom<span style="color: #66cc66;">,</span> score <span style="color: #ff7700;font-weight:bold;">in</span> scores:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nom<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>score<span style="color: black;">&#41;</span>
...
<span style="color: black;">Monique</span>
<span style="color: #ff4500;">3</span>
David
<span style="color: #ff4500;">10</span>
Dick
<span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>Cela marche avec des itérables plus gros, bien entendu. C&#8217;est aussi particulièrement utile avec des dictionnaires car on peut les transformer en itérable de tuples :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> scores <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Monique'</span>: <span style="color: #483d8b;">'3'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'David'</span>: <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Dick'</span>: <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> scores<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Monique'</span><span style="color: black;">&#93;</span>
<span style="color: #483d8b;">'3'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> scores.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># transformation !</span>
dict_items<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Monique'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'3'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'David'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'Dick'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> nom<span style="color: #66cc66;">,</span> score <span style="color: #ff7700;font-weight:bold;">in</span> scores.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nom<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>score<span style="color: black;">&#41;</span>
...
<span style="color: black;">Monique</span>
<span style="color: #ff4500;">3</span>
David
<span style="color: #ff4500;">10</span>
Dick
<span style="color: #ff4500;">1</span></pre></td></tr></table></div>

<p>Tout aussi utile, mais plus compliqué, est l&#8217;usage de l&#8217;unpacking dans l&#8217;appel de fonction. Pour cela, on utilise <a href="http://sametmax.com/operateur-splat-ou-etoile-en-python/">l&#8217;opérateur splat</a>, l&#8217;étoile en Python.</p>
<p>Soit une fonction qui additionne des nombres :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> add<span style="color: black;">&#40;</span>a<span style="color: #66cc66;">,</span> b<span style="color: #66cc66;">,</span> c<span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">return</span> a + b + c
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> add<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">6</span></pre></td></tr></table></div>

<p>Oui, imaginons que je suis complètement débile, et que j&#8217;ai cette fonction pérave dans mon code. Vous noterez dans les articles que je l&#8217;utilise souvent sur le blog. C&#8217;est la fonction fourre tout pour expliquer un truc quand j&#8217;ai pas d&#8217;idée.</p>
<p>Maintenant, imaginez que je veuille additionner des canards. Si, ça marche en Python :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">'riri'</span> + <span style="color: #483d8b;">'fifi'</span> + <span style="color: #483d8b;">'loulou'</span> <span style="color: #808080; font-style: italic;"># what the duck ?</span>
<span style="color: #483d8b;">'rirififiloulou'</span></pre></td></tr></table></div>

<p>Maintenant je me refais mon tuples de canards :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #808080; font-style: italic;"># nous entrerons dans la bande à picsou, youhou</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> duckyou <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'riri'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'fifi'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'loulou'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Si je veux utiliser ma fonction pourrie pour mon use case stupide, je ferai ceci :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> add<span style="color: black;">&#40;</span>duckyou<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> duckyou<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> duckyou<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'rirififiloulou'</span></pre></td></tr></table></div>

<p>Voilà une perte de productivité intolérable, c&#8217;est pas comme ça qu&#8217;on va faire fructifier son sou fétiche.</p>
<p>On peut forcer l&#8217;unpacking avec l&#8217;étoile :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> add<span style="color: black;">&#40;</span>*duckyou<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'rirififiloulou'</span></pre></td></tr></table></div>

<p>Si on oublie l&#8217;étoile, le premier paramètre reçoit tout le tuple, et les autres paramètres rien :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> add<span style="color: black;">&#40;</span>duckyou<span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    add<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: add<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> missing <span style="color: #ff4500;">2</span> required positional arguments: <span style="color: #483d8b;">'b'</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #483d8b;">'c'</span></pre></td></tr></table></div>

<p>Les fonctions ont même le droit à un bonus car on peut unpacker des dictionnaires en utilisant la <strong>double</strong> étoile. Ca ne marche qu&#8217;avec les fonctions, et ça va déballer le dico pour que chaque paire clé/valeur soit passée comme nom et valeur de l&#8217;argument :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> pas_add<span style="color: black;">&#40;</span>arg1<span style="color: #66cc66;">,</span> arg2<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>arg1<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>arg2<span style="color: black;">&#41;</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pas_add<span style="color: black;">&#40;</span>arg1<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;Je suis la valeur 1&quot;</span><span style="color: #66cc66;">,</span> arg2<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;Je m'en branle de qui tu es&quot;</span><span style="color: black;">&#41;</span>
Je suis la valeur <span style="color: #ff4500;">1</span>
Je m<span style="color: #483d8b;">'en branle de qui tu es
&gt;&gt;&gt; dicocorico = {'</span>arg1<span style="color: #483d8b;">': '</span>cotcot<span style="color: #483d8b;">', '</span>arg2<span style="color: #483d8b;">': '</span>ouai je pête un cable<span style="color: #66cc66;">,</span> l\<span style="color: #483d8b;">'avion me soule'</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pas_add<span style="color: black;">&#40;</span>**dicocorico<span style="color: black;">&#41;</span>
cotcot
ouai je pête un cable<span style="color: #66cc66;">,</span> l<span style="color: #483d8b;">'avion me soule</span></pre></td></tr></table></div>

<p>Quand on unpacke des paramètres, il faut s&#8217;assurer que le nombre d&#8217;arguments passé n&#8217;est pas supérieur à ceux existant, sinon ça plante :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> dicocorico <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'arg1'</span>: <span style="color: #483d8b;">'cocot'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'arg2'</span>: <span style="color: #483d8b;">'ouai je pête un cable, l<span style="color: #000099; font-weight: bold;">\'</span>avion me soule'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'dang'</span>: <span style="color: #483d8b;">'je suis en trop et ça fait chier tout le monde'</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pas_add<span style="color: black;">&#40;</span>**dicocorico<span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    pas_add<span style="color: black;">&#40;</span>**dicocorico<span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: pas_add<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> got an unexpected <span style="color: #dc143c;">keyword</span> argument <span style="color: #483d8b;">'dang'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> stuplet <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pas_add<span style="color: black;">&#40;</span>*stuplet<span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> 
    pas_add<span style="color: black;">&#40;</span>*stuplet<span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: pas_add<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> takes <span style="color: #ff4500;">2</span> positional arguments but <span style="color: #ff4500;">3</span> were given</pre></td></tr></table></div>

<p>Par contre, rien ne vous empêche de fournir moins d&#8217;arguments et de remplir les autres à la main :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">def</span> encore_add<span style="color: black;">&#40;</span>a<span style="color: #66cc66;">,</span> b<span style="color: #66cc66;">,</span> c<span style="color: #66cc66;">,</span> d<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> a + b + <span style="color: #ff4500;">0</span> + c + d <span style="color: #808080; font-style: italic;"># je feinte</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> encore_add<span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> *stuplet<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">16</span></pre></td></tr></table></div>

<p>Et on peut bien entendu faire le mega mix. Par exemple, prenons la fonction <code>print</code>, dont la signature accepte une infinité d&#8217;arguments positionnels et quelques arguments nommés :</p>
<p><code>print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)</code></p>
<p>Aller, on va lui unpacker sa mère :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> ducks <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'riri'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'fifi'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'loulou'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># is this duck typing ?</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> keywords <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'sep'</span>: <span style="color: #483d8b;">' / '</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;end&quot;</span>: <span style="color: #483d8b;">&quot; : vous êtes du coin ? <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'picsou'</span><span style="color: #66cc66;">,</span> *ducks<span style="color: #66cc66;">,</span> **keywords<span style="color: black;">&#41;</span>
picsou / riri / fifi / loulou : vous êtes du coin ?</pre></td></tr></table></div>

<p>Ça c&#8217;est fait.</p>
<h2>Python 3, c&#8217;est du chocolat</h2>
<p>En Python 3, l&#8217;unpacking a été amélioré, et on peut maintenant faire de l&#8217;unpacking partiel :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #808080; font-style: italic;"># exemple 100% repompé d'un autre article du blog. Duck it.</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> l <span style="color: #66cc66;">=</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> l
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> *b <span style="color: #66cc66;">=</span> l
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a
<span style="color: #ff4500;">0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: #66cc66;">,</span> *b<span style="color: #66cc66;">,</span> c <span style="color: #66cc66;">=</span> l
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a
<span style="color: #ff4500;">0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> b
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> c
<span style="color: #ff4500;">4</span></pre></td></tr></table></div>

<p>Ce qui peut être très pratique sur les longs itérables. Comment obtenir la dernière ligne d&#8217;un fichier ?</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> *contenu<span style="color: #66cc66;">,</span> dernire_ligne <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/etc/fstab'</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> dernire_ligne
<span style="color: #483d8b;">'UUID=0e8c3132-8fa2-46d5-a541-2890db9b371f none            swap    sw              0       0<span style="color: #000099; font-weight: bold;">\n</span>'</span></pre></td></tr></table></div>

<p>Ou alors, dans une boucle :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> initiale<span style="color: #66cc66;">,</span> *reste <span style="color: #ff7700;font-weight:bold;">in</span> ducks:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>initiale<span style="color: black;">&#41;</span>
...
<span style="color: black;">r</span>
f
l</pre></td></tr></table></div>


feed_id: http://sametmax.com/?p=13047
title: Comment arrivent les plans à 3 ? 5 Recently updated !
uri: Comment-arrivent-les-plans-à-3-2
url: http://sametmax.com/comment-arrivent-les-plans-a-3/
content:
<p>Au début, on se demande comment parler à l&#8217;autre. Et comment on fait pour toucher ? Embrasser ? Baiser ? Obtenir une fellation ? Une sodomie ? Amener un scénario, un jeu SM ?</p>
<p>Et puis on grandit et on passe de l&#8217;autre côté de la barrière, et à chaque fois on se dit que c&#8217;était pas si mystérieux que ça au final.</p>
<p>Mais il reste toujours des situations inconnues, qui apparaissent obscures : par exemple, comment on arrive à un threesome, bordel ?</p>
<p>Comme d&#8217;habitude, je n&#8217;ai pas de recette magique, mais je peux vous donner quelques exemples de situations.</p>
<h2>Promotion sur canapé</h2>
<p>Marc, Marie et Mathilde ont orienté le rétroprojecteur vers le plafond pour regarder un film comme des loques, allongés sur deux canapés poussés l&#8217;un contre l&#8217;autre. Marc et Marie sortent ensemble, Marc et Mathilde ont fleurté. Tous les 3 sont sexuellement décontractés et ont déjà parlé de cul à table. Ils se connaissent, ils ont plusieurs soirées derrière eux.</p>
<p>En plein film, Marc caresse le bras de Marie, puis descend lentement vers sa chatte, sans y penser. Il finit par la caresser discrètement, et emporté, lui cale un doigt. Marie reste calme, mais Mathilde s&#8217;en aperçoit. Elle soulève le shirt de Marie, et commence à lui toucher un sein, puis à le prendre dans sa bouche. Tout en regardant le film, Marc et Mathilde s&#8217;occupent de Marie. Puis l&#8217;excitation monte, et Marc retire le pantalon de Marie pour lui faire un cuni&#8230;</p>
<p>Que s&#8217;est-t-il passé ?</p>
<p>Les 3 personnes se connaissaient. Elles sont à l&#8217;aise sexuellement. Elles ont déjà parlé de sexe.</p>
<p>En effet, on ne peut pas faire ça avec tout le monde : seul un certain type de personnes se retrouvent dans ces threesomes, les gens à l&#8217;aise avec le cul. Si vous avez du mal à assumer votre sexualité, si pour vous la fellation est un événement rare, ne tentez pas le plan à 3 tout de suite. Courir avant de marcher, tout ça&#8230;</p>
<p>Ensuite, ils savent qui ils sont : ils se sont vu plusieurs fois, ont parlé de sexe, se sont évalués. La prise de risque est allégée. </p>
<p>Ils sont seuls, dans une situation confortable, intime, et tout escalade doucement, naturellement. Personne n&#8217;a essayé de lancer un plan à 3. Ça s&#8217;est fait, non pas parce que chaque pas à amené vers, mais parce qu&#8217;aucun pas n&#8217;a été bloqué.</p>
<p>Car quand il s&#8217;agit de sexe, si une envie n&#8217;est pas satisfaite, c&#8217;est toujours imposé par une forme ou une autre de blocage. Il ne s&#8217;agit donc pas de pousser, mais d&#8217;être dans un contexte fluide, sans blocage.</p>
<h2>Comment on fait, putain ?</h2>
<p>La putain, est aussi la porte d&#8217;entrée aux plan à 3. Julien et Jérémy vont dans un bordel, embauchent une professionnelle en lui demandant si ils peuvent être deux pendant la séance. Ils se rejoignent dans la chambre, surmontent leurs inhibitions et se déshabillent. Au début ils hésitent, mais la prostituée connaît son métier et commence par en sucer un, exposant sa croupe à l&#8217;autre. Invité, le second la pénètre après avoir mis un préservatif. Les deux amis ne se toucheront pas, nullement intéressés l&#8217;un par l&#8217;autre, mais trouveront agréable l&#8217;expérience de partager une même femme.</p>
<p>Encore une fois, on note que tout le monde ne peut pas se retrouver dans cette situation : il faut des gens à l&#8217;aise avec l&#8217;idée de prostitution, et qui acceptent de se dévoiler, plus nus que jamais, l&#8217;un à l&#8217;autre dans une activité sexuelle.</p>
<p>Ce sont des amis, ils se connaissent. On en revient donc à la notion de confort et de confiance.</p>
<p>De son côté, la femme, accepte de prendre deux hommes en même temps, ce qui n&#8217;est pas forcément toujours le cas. Croire que les putes acceptent tout et que la permission est optionnelle est l&#8217;erreur des gens qui confondent sexe payé et esclavage. Une prostituée est une femme ordinaire, qui mérite le même respect.</p>
<h2>Je ne fais pas ça d&#8217;habitude</h2>
<p>Ingrid, Isabelle et Ignace ont tous beaucoup bu. Ignace a été gogo danseur par le passé et a fait sérieusement monté la température sur scène, mais maintenant ils se détendent, assis sur le même canapé. Ils ne parlent pas, ils sont dans la torpeur que le mélange de musique forte, d&#8217;éthanol et d&#8217;activité physique finit toujours par produire.</p>
<p>Ignace a lancé cette soirée chez lui, comme de nombreuses autres. Tout le monde le connaît comme quelqu&#8217;un de sociable, connaissant beaucoup de gens. Car il aime ça, il aime parler à autrui. Il aime aider. Il aime recevoir. Et toutes les personnes ce soir le savent.</p>
<p>Pour ne rien gâcher, Ignace est beau gosse, officiellement bi, et parle de sexe ouvertement. Il sera donc le pivot.</p>
<p>Dans le flou flottant de cet instant, les deux filles se reposent sur Ignace qui en embrasse une sur la tête. Il met ses bras autour d&#8217;elles. Ils restent ainsi un moment qui peut paraître long (mais difficile à évaluer car on perd la notion du temps dans ces conditions), affectueusement. Les mains d&#8217;Ignace caressent légèrement Ingrid et Isabelle. L&#8217;une l&#8217;embrasse sur la joue. L&#8217;autre l&#8217;embrasse sur la main. Il peut se passer un temps important entre deux baisers. Mais il décroit, jusqu&#8217;à ce que leurs corps remuent un peu, légèrement, l&#8217;un contre l&#8217;autre. Alors ils s&#8217;en vont dans la chambre.</p>
<p>Une fois de plus : les personnes sont connues, le milieu est sûr, il y a du confort et de la confiance, et bien entendu une aisance avec le sexe. L&#8217;alcool et le bruit catalysent cela, donnant une impression de proximité, voir d&#8217;intimité. </p>
<h2>Ou autres</h2>
<p>Ce ne sont pas les seules possibilités. Je pourrais parler de la drogue, des clubs échangistes, des plans à 3 planifiés avec son/sa partenaire&#8230;</p>
<p>Mais l&#8217;idée reste là :</p>
<ul>
<li>Ça ne se fait pas avec n&#8217;importe qui : des gens qu&#8217;on connait, envers lesquels on a confiance, qui sont à l&#8217;aise avec le cul.
</li>
<li>La prise de risque doit être faible. Il ne doit pas y avoir de blocage. Le reste suit juste son cours.</li>
<li>Le contexte joue : alcool, confort, joie, côté naturel de la chose.</li>
</ul>
<p>Ceci s&#8217;applique même pour l&#8217;exemple avec la prostituée. Si vous ne le voyez pas, c&#8217;est que vous avez encore un blocage quelque part. Le premier blocage à faire sauter, c&#8217;est le vôtre.</p>
<p>Une autre chose importante là-dedans, c&#8217;est qu&#8217;aucun des acteurs n&#8217;a la peur d&#8217;être rejeté. Non pas qu&#8217;ils ont la certitude que ça va marcher, mais plutôt :</p>
<ul>
<li>Qu&#8217;ils n&#8217;ont pas l&#8217;objectif &#8220;threesome&#8221; en tête. Juste de passer un bon moment.</li>
<li>Ils sont ok à l&#8217;idée qu&#8217;on dise non. C&#8217;est absolument normal.</li>
<li>Ils se sont déjà fait dire non bien des fois.</li>
</ul>
<p>Autre chose : personne n&#8217;a rien demandé. Ils font. Pour ce genre de choses, il est plus facile de demander pardon que la permission.</p>


feed_id: http://sametmax.com/?p=12972
title: Prendre le contrôle d’internet ? C’est possible ! Dégainez & Tirez avec Trigger Happy 4
uri: Prendre-le-contrôle-d-internet-C-est-possible-Dégainez-Tir
url: http://sametmax.com/prendre-le-controle-dinternet-cest-possible-degainez-tirez-avec-trigger-happy/
content:
<p style="text-align: center;"><em><small>Ceci est un post invité de <a href="http://sametmax.com/author/foxmask/">foxmask</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>.</small></em></p>
<p>&#8220;C&#8217;est l&#8217;histoire d&#8217;un mec qu&#8217;est su&#8217;l&#8217;pont de l&#8217;Alma et regarde dans&#8221; &#8230; le python, et comme il débute, se demande mais putain de bordel, des projets à la con à pondre pour se lancer à l&#8217;assaut d&#8217;un langage, c&#8217;est toujours les mêmes trucs chiants que plus personne n&#8217;a envie de voir tels : forum, blog, wiki, cms. Alors comment être novateur un poil plus que ces projets sans (plus aucun) défit technique ?</p>
<p>A cette question je me suis dit, pourquoi ne pas produire &#8220;simplement&#8221; (toute proportion gardée) un équivalent libre au célébrissime <a href="https://www.ifttt.com">IFTTT</a> ?</p>
<h2>Mais qu&#8217;est-ce ? </h2>
<p>IFTTT est un service qui vous permet de brancher entre eux, les services internet où vous possédez un compte, comme Twitter, Facebook pour ne citer qu&#8217;eux (parce que la liste est longue comme un python au moins;) Et donc quand un évènement défini se produit sur votre compte twitter, genre un tweet de votre poto tombe, le service réagit au quart de tour pour rebalancer les données ailleurs, sur Facebook, un blog et n&#8217;importe quoi qui vous chante.</p>
<p>Hé bien cet équivalent libre est <a href="https://github.com/foxmask/django-th">Trigger Happy</a>, et ce &#8220;principe&#8221; décrit ci-dessus défini un ESB (Entreprise Service Bus, très connu du monde Java), un BUS qui récupère des données de droite et vous les expédie à gauche.</p>
<p>Wikipedia le défini ainsi :</p>
<blockquote="wikipedia"><p>
L&#8217;enterprise service bus (ESB) est une technique informatique intergicielle. Son but est avant tout de permettre la communication des applications qui n&#8217;ont pas été conçues pour fonctionner ensemble</p></blockquote>
<h2>Pourquoi un tel projet ?</h2>
<p>3 aspects :</p>
<ul>
<li>Avec ce projet je me suis lancé le défit d&#8217;arriver à cerner au mieux Django et abordé au mieux Python.</li>
<li>Comme tout ce que j&#8217;entreprends, se produit par pur réaction allergique à un truc qui m&#8217;a gonflé, explications les zamis :<br />
Au début on fait (plus ou moins) comme tout le monde, sa veille techno à partir de flux RSS de sites web choisis, avec un lecteur de flux RSS moins bien choisi comme iGoogle à une certaine époque ou encore &#8230; Google Reader.<br />
Là le truc qui m&#8217;a pris le chou, ce fut d&#8217;avoir dans Evernote, le résultats des flux RSS de mes sites favoris complètement atrophiés.<br />
Du genre &#8220;il a été à l&#8217;école&#8221; devenait &#8220;il a t l&#8217;cole&#8221;. Or le problème ne vient pas d&#8217;Evernote qui affiche parfaitement nos chers caractères latins, mais de IFTTT qui les bouffait au passage. Outre IFTTT il existe des versions payantes de services mais qui sont vite très vite limitées dans le nombre de triggers déclenchés que sont Zapier et CloudWork.
</li>
<li>
Le dernier aspect concerne sa chère vie privé.<br />
Oui en effet, pour que IFTTT puisse récupérer des donnés d&#8217;un service à l&#8217;autre, il faut que vous ayez un compte sur chaque service comme Twitter et Facebook. Pourquoi IFTTT en a besoin ? Pour que, &#8220;en votre nom&#8221;, avec les accréditations que vous leur octroyez, puisse lire/écrire les informations de part et d&#8217;autre.<br />
Mais pourquoi faire confiance à IFTTT / Cloudwork / Zapier ? Pourquoi leur offrir NOS accréditations les yeux fermés ?<br />
Trigger Happy repond à la question puisque l&#8217;application vous appartient, les accréditations obtenues de Twitter, Facebook etc, sont stockées dans VOTRE application Trigger Happy. Et personne n&#8217;ira les exploiter pour voir ce que vous faites sur vos comptes.
</li>
</ul>
<h2>Comment fonctionne le projet ?</h2>
<p>Dans la version simplifiée ceci donne :<br />
<div id="attachment_5019" style="width: 420px" class="wp-caption aligncenter"><a href="media/ed04294d.trigger-happy-working.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger-happy-working.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/ed04294d.trigger-happy-working.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger-happy-working.png" alt="Trigger Happy wokring process" width="410" height="351" class="size-full wp-image-5019" /></a><p class="wp-caption-text">Image tirée de ma main &#8220;gauche&#8221; gauche, enfin la gauche pas adroite</p></div><br />
De part et d&#8217;autres (dans les nuages) on a les services qui nous intéressent<br />
Les éclairs oranges sont les connecteurs qui permettent de dialoguer avec les services<br />
Au milieu .. (non ne coule pas une rivière) le moteur Trigger Happy qui gère, via les connecteurs, l&#8217;échange des données.</p>
<p>Dans la version complète ceci donne :<br />
<div id="attachment_5018" style="width: 567px" class="wp-caption aligncenter"><a href="media/1ad209e2.th_esb.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/th_esb.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/1ad209e2.th_esb.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/th_esb.png" alt="Trigger Happy Micro ESB" width="557" height="347" class="size-full wp-image-5018" /></a><p class="wp-caption-text">Trigger Happy Micro ESB</p></div></p>
<p>On a au milieu un &#8220;tube&#8221; (pipeline) qui va permettre, via des &#8220;command&#8221; &#038; settings &#038; url &#038; service provider, d&#8217;identifier les services &#8220;django th 1, 2, 3, 4&#8243;.<br />
A un moment donné, à l&#8217;entrée du tube, arrive un &#8220;flux&#8221; de donnés identifié pour admettons &#8220;django th 1&#8243; aka un flux RSS (au pif) puis on identifie une destination, admettons &#8220;django th 2&#8243; aka &#8220;twitter&#8221;, et les données collectées repartent donc du tube vers twitter, comme le service s&#8217;attend à les recevoir.</p>
<h2>Dans la vraie vie comment ça se passe  ?</h2>
<p>Ça se passe bien mon zami : je m&#8217;en va (la fote est volontaire tout comme l&#8217;reste;) vous montrer la création d&#8217;un trigger, permettant d&#8217;extraire les billets du flux de mon blog et de les renvoyer sur Twitter en 5 étapes :</p>
<p>Ici en premier lieu vous pouvez voir la liste des services que Trigger Happy gere pour l&#8217;utilisateur courant (mézigues)</p>
<div id="attachment_5023" style="width: 614px" class="wp-caption aligncenter"><a href="media/4c2d2385.trigger_happy_services.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_services.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/8bce876d.trigger_happy_services-1024x539.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_services-1024x539.png" alt="Trigger Happy : services activés" width="604" height="318" class="size-large wp-image-5023" /></a><p class="wp-caption-text">Trigger Happy : services activés</p></div>
<p>Puis l&#8217;accueil de l&#8217;appli où on remarquera que je suis radin en nombre de trigger affichés par page parce que &#8230; je me sers de l&#8217;appli via un browser sur mon smartphone m&#8217;sieur &#8216;dames :<br />
<div id="attachment_5022" style="width: 614px" class="wp-caption aligncenter"><a href="media/79f7ec87.trigger_happy_home.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_home.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/481b4d11.trigger_happy_home-1024x595.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_home-1024x595.png" alt="Trigger Happy : Accueil" width="604" height="351" class="size-large wp-image-5022" /></a><p class="wp-caption-text">Trigger Happy : Accueil</p></div></p>
<p>Etape 1:<br />
<div id="attachment_5024" style="width: 621px" class="wp-caption aligncenter"><a href="media/658ab035.trigger_happy_step1.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step1.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/658ab035.trigger_happy_step1.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step1.png" alt="Trigger Happy : Etape 1 de la création d&#039;un trigger" width="611" height="315" class="size-full wp-image-5024" /></a><p class="wp-caption-text">Choix du service fournissant les données</p></div></p>
<p>Etape 2:<br />
<div id="attachment_5025" style="width: 709px" class="wp-caption aligncenter"><a href="media/caf951ed.trigger_happy_step2.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step2.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/caf951ed.trigger_happy_step2.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step2.png" alt="Trigger Happy : Etape 2 de la création d&#039;un trigger" width="699" height="329" class="size-full wp-image-5025" /></a><p class="wp-caption-text">nommage du service et fourniture de l&#8217;origine des données</p></div></p>
<p>Etape 3:<br />
<div id="attachment_5026" style="width: 602px" class="wp-caption aligncenter"><a href="media/899b6c46.trigger_happy_step3.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step3.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/899b6c46.trigger_happy_step3.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step3.png" alt="Trigger Happy : Etape 3 de la création d&#039;un trigger" width="592" height="310" class="size-full wp-image-5026" /></a><p class="wp-caption-text">Choix du service accueillant les données</p></div></p>
<p>Etape 4:<br />
<div id="attachment_5027" style="width: 670px" class="wp-caption aligncenter"><a href="media/93f38121.trigger_happy_step4.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step4.png" class="grouped_elements" rel="tc-fancybox-group12972"><img src="media/93f38121.trigger_happy_step4.png" data-original-source="http://www.foxmask.bzh/wp-content/uploads/2014/12/trigger_happy_step4.png" alt="Trigger Happy : Etape 4 de la création d&#039;un trigger" width="660" height="351" class="size-full wp-image-5027" /></a><p class="wp-caption-text">Trigger Happy : Etape 4 de la création d&#8217;un trigger</p></div></p>
<p>Ensuite le moment venu, se déclenche ce trigger, et pour en voir le résultat, on peut consulter <a href="http://www.foxmask.bzh/post/2014/11/27/django-paris-numa-novembre-2014-demo-live/">le billet</a> que j&#8217;avais préparé le mois dernier pour une présentation Django Paris. Et qui au moment de la publication du billet, à 19h15 pétantes, est tombé sur <a href="https://twitter.com/foxmask/status/538033340155432960">twitter</a> directement et <a href="https://www.evernote.com/pub/foxmask1/Django#st=p&#038;n=e47e8324-ad7e-4b4a-bf4e-0823642b9d3a">Evernote</a> dans la foulée.</p>
<p>Voilà ! </p>
<p>Le défit est parti et n&#8217;attend plus qu&#8217;à ce que le nombre de services croissent. Pour cela rien de plus simple, j&#8217;ai fait une doc expliquant comment pondre un module django qui exploite le service de votre choix tel Buffer, Trello, Dropbox et j&#8217;en passe et des meilleurs. Tout ce dont on a besoin : l&#8217;API du service visé en python, créer un compte pour avoir accès au service et suivre le howto sur <a href="http://trigger-happy.readthedocs.org/en/latest/new_module.html">readthedoc</a>  </p>
<p>Last but not least aux dev : ca tourne avec django 1.7 / Python 2.7 et 3.4</p>
<p>Dernier détail: comme je suis sûr que vous vous demandez pourquoi ce nom de projet ? <a href="media/11eb85e9.trigger-happy.png" data-original-source="http://trigger-happy.eu/static/django-paris-novembre-2014/trigger-happy.png" class="grouped_elements" rel="tc-fancybox-group12972">C&#8217;est un perso de la franchise Skylander</a> auquel joue mon fils et comme le projet &#8220;trigger&#8221; à tirelarigot sur l&#8217;net, ca collait pile poil :)</p>


feed_id: http://sametmax.com/?p=13072
title: Bridge HTTP/WAMP 5
uri: Bridge-HTTP-WAMP-3-Recently-updated
url: http://sametmax.com/bridge-httpwamp/
content:
<p>Il y a 4 gros freins à l&#8217;adoption de <a href="http://sametmax.com/presentation-de-wamp-round-2/">WAMP</a> :</p>
<ol>
<li>L&#8217;incompréhension de la techno. Les gens ne voient pas à quoi ça sert, ce qu&#8217;ils peuvent faire avec, et ont peur. Logique. Je vais pas les blâmer, c&#8217;est pareil avec toute nouvelle techo. S&#8217;investir dans un nouveau truc a un coût, surtout un truc jeune.</li>
<li>La doc. je vais travailler sur la question, mais c&#8217;est un travail de fond.</li>
<li>L&#8217;API : ça va avec les deux points plus haut. Il faut quelque chose de plus haut niveau. L&#8217;API <a href="http://sametmax.com/introduction-a-wamp-en-python/">flaskesque</a> est un bon début, il faut maintenant continuer dans ce sens.</li>
<li>L&#8217;intégration avec les anciennes technos. Par exemple, un site Django. Personne n&#8217;a envie de mettre toute son ancienne stack à la poubelle.</li>
</ol>
<p>Toute les libs qui introduisent une nouvelle façon de travailler rencontrent ce problème. Quand les ORM sont sortis, c&#8217;était pareil. Quand les Django et Rails, et Symfony sont sortis, c&#8217;était pareil.</p>
<p>Mais puisqu&#8217;on le sait, on peut agir.</p>
<p>Les 3 premiers points ont déjà un début de solution, ce qui nous intéresse c&#8217;est donc le 4ème point.</p>
<p>Il y a de nombreuses choses à faire pour l’intégration : authentification, actions bloquantes, communications&#8230;</p>
<p>On ne peut pas tout résoudre d&#8217;un coup, mais une solution qui ratisse large serait de créer un bridge HTTP/WAMP.</p>
<p>Le principe : faire un client WAMP qui soit aussi client HTTP avec une API REST.</p>
<h2>Fonctionnement</h2>
<p>En envoyant des requêtes HTTP avec un <a href="https://github.com/progrium/pyjwt">webtoken</a> pour s&#8217;authentifier, on peut faire un register/subscribe/call/publish sur le bridge en spécifiant une URL de callback. Le bridge transmet tout ça à routeur WAMP. Quand un événement arrive sur le bridge qui concerne une des URLs de callback, il fait une requête sur l&#8217;URL avec les infos arrivées via WAMP.</p>
<p>API :</p>
<p><code>POST /register/</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// token d'authentification</span>
    token<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fdjsklfqsdjm&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// On enregistre des urls de callbacks pour chaque &quot;function&quot; exposées en RPC</span>
    <span style="color: #006600; font-style: italic;">// Quand le bridge reçoit un appel RPC via WAMP, il fera une requête POST</span>
    <span style="color: #006600; font-style: italic;">// sur la bonne URL. Votre app récupère les données via POST, et retourne</span>
    <span style="color: #006600; font-style: italic;">// du JSON que le bridge va transmettre via WAMP.</span>
    endpoints<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;nom_fonction_1&quot;</span><span style="color: #339933;">:</span>  <span style="color: #3366CC;">&quot;http://localhost:8080/wamp/rpc/nom_fonction_1/&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;nom_fonction_2&quot;</span><span style="color: #339933;">:</span>  <span style="color: #3366CC;">&quot;http://localhost:8080/wamp/rpc/nom_fonction_2/&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><code>POST /subscribe/</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    token<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fdjsklfqsdjm&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// On enregistre des urls de callbacks chaque abonnement à un topic.</span>
    <span style="color: #006600; font-style: italic;">// Quand le bridge reçoit un message PUB via WAMP, il fera une requête POST</span>
    <span style="color: #006600; font-style: italic;">// sur la bonne URL. Votre app récupère les données via POST.</span>
    endpoints<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;nom_fonction_1&quot;</span><span style="color: #339933;">:</span>  <span style="color: #3366CC;">&quot;http://localhost:8080/wamp/pub/nom_fonction_1/&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;nom_fonction_2&quot;</span><span style="color: #339933;">:</span>  <span style="color: #3366CC;">&quot;http://localhost:8080/wamp/pub/nom_fonction_2/&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><code>POST /call/nom_fonction/</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    token<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fdjsklfqsdjm&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// Le bridge fera l'appel RPC, récupère la valeur de retour, et la renvoie</span>
    <span style="color: #006600; font-style: italic;">// à cette URL via POST ou une erreur 500 en cas d'exception.</span>
    callback<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://localhost:8080/wamp/callback/nom_fonction&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// Les params à passer à l'appel RPC</span>
    params<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'param1'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'param2'</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><code>POST /publish/nom_sujet/</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    token<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fdjsklfqsdjm&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// Le bridge fera la publication WAMP</span>
    <span style="color: #006600; font-style: italic;">// Les params à passer lors de la publication</span>
    params<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'param1'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'param2'</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On peut rajouter des fioritures : recharger le fichier de config qui contient les API keys, se désabonner, désinscrire un callback RPC, etc. </p>
<p>Bien entendu, du fait d&#8217;avoir un intermédiaire, c&#8217;est peu performant, mais suffisant pour permettre une communication entre des apps existantes et vos apps WAMP et mettre un pied dedans.</p>
<h2>Intégration poussée</h2>
<p>Ceci permet une intégration générique, de telle sorte que tout le monde puisse intégrer son app facilement avec quelques requêtes HTTP. Néanmoins, avoir un plugin pour son framework plug and play faciliterait la vie de beaucoup de gens.</p>
<p>Donc la partie 2, c&#8217;est de faire des apps pour les frameworks les plus courants qui wrappent tout ça.</p>
<p>Par exemple, pour Django, ça permettrait de faire :</p>
<p><code>settings.py</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">WAMP_BRIDGE_URL <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;http://localhost:8181/&quot;</span></pre></td></tr></table></div>

<p><code>urls.py</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> wamp_bridge.<span style="color: black;">adapters</span>.<span style="color: black;">django</span> <span style="color: #ff7700;font-weight:bold;">import</span> dispatcher
&nbsp;
urlpatterns +<span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span><span style="color: #483d8b;">'/wamp/, dispatcher),
    ...
)</span></pre></td></tr></table></div>

<p><code>views.py</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> wamp_bridge.<span style="color: black;">adapters</span>.<span style="color: black;">django</span> <span style="color: #ff7700;font-weight:bold;">import</span> publish<span style="color: #66cc66;">,</span> call<span style="color: #66cc66;">,</span> rpc<span style="color: #66cc66;">,</span> sub
&nbsp;
<span style="color: #66cc66;">@</span>rpc<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nom_fonction_1<span style="color: black;">&#40;</span>val1<span style="color: #66cc66;">,</span> val2<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># faire un truc</span>
&nbsp;
<span style="color: #66cc66;">@</span>sub<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nom_topic_1<span style="color: black;">&#40;</span>val1<span style="color: #66cc66;">,</span> val2<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># faire un truc</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> vue_normale<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    publish<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sujet'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'arg1'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    resultat <span style="color: #66cc66;">=</span> call<span style="color: black;">&#40;</span><span style="color: #483d8b;">'function'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'arg1'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ca répond pas à des questions du genre : &#8220;comment je fais pour garder mon authentification Django&#8221; mais c&#8217;est déjà super glucose.</p>
<h2>Implémentation</h2>
<p>On peut créer un bridge dans plein de langages, mais je pense que Python est le plus adapté.</p>
<p>Les clients JS utiliseraientt de toute façon nodeJS, qui n&#8217;a pas besoin de bridge, puisque déjà asynchrone. Un routeur en C demanderait de la compilation. PHP est trop moche. Java, c&#8217;est tout un bordel à setuper à chaque fois. C#, si il faut se taper Mono sous Linux&#8230;</p>
<p>En prime, le routeur crossbar est déjà en Python, donc a déjà tout sous la main pour le faire. On peut même penser à l&#8217;intégrer à crossbar plus tard histoire que ce soit batteries included.</p>
<p>Il faut une implémentation Python 2 et Python 3, donc une avec Twisted, et une avec asyncio.</p>
<p>Pour le client twisted, on peut fusionner le client WAMP ordinaire avec <a href="http://twistedmatrix.com/documents/14.0.0/web/howto/web-in-60/index.html</a> et <a href="https://github.com/dreid/treq">treq</a>.</p>
<p>Pour asyncio, il y a <a href="https://github.com/KeepSafe/aiohttp">aiohttp</a> qui fait client et serveur.</p>
<p>On met les clés API dans un fichier de conf ou une variable d&#8217;env, une auth via token, et yala.</p>
<p>C&#8217;est le genre de projet intéressant car pas trop gros, mais suffisamment complexe pour être un challenge surtout qu&#8217;il faudra des tests unitaires partout, de la doc, bref un truc propre.</p>
<p>Je laisse les specs là, des fois qu&#8217;il y ait quelqu&#8217;un qui ait des envies de code cet hiver et cherche un projet open source dans lequel se lancer.</p>
<p>Si on se sent un peut foufou, on peut même transformer ça en bridget HTTP <=> anything, avec des backends pour ce qu&#8217;on veut : IRC, XMPP, Redis, Trigger Happy&#8230;</p>


feed_id: http://sametmax.com/?p=15615
title: Qu’est-ce que les websockets et à quoi ça sert ? 8 Recently updated !
uri: Qu-est-ce-que-les-websockets-et-à-quoi-ça-sert-4-Recently-upd
url: http://sametmax.com/quest-ce-que-les-websockets-et-a-quoi-ca-sert/
content:
<blockquote><p>Le protocole WebSocket vise à développer un canal de communication full-duplex sur un socket TCP.</p></blockquote>
<p>LOL. C&#8217;est clair non ?</p>
<p>Vous inquiétez pas, tonton Sam est là.</p>
<p>Le Web a évolué. On est passé de Gopher a HTTP 1 puis 1.1. Et on a eu AJAX pour rafraîchir la page sans tout recharger.</p>
<p>Et maintenant on a des apps complètes qui font des centaines de requêtes au serveur alors même que l&#8217;utilisateur ne change pas de page. D&#8217;ailleurs, je parie que plein de gens ne savent même plus ce qu&#8217;est une page&#8230;</p>
<p>Le problème c&#8217;est qu&#8217;AJAX, c&#8217;est toujours HTTP, et HTTP est sans état (stateless) : il ne garde aucune information en mémoire d&#8217;une requête à l&#8217;autre. Ça a des avantages, mais cela implique qu&#8217;à chaque requête, il faut ouvrir une connexion et la refermer. Ce qui bouffe quelques ms à chaque fois, et d&#8217;autant plus si on utilise SSL.</p>
<p>Une autre limite, c&#8217;est que le serveur ne peut pas envoyer de données au client (ici le navigateur) si le client ne fait pas une requête au préalable. Du coup, pour savoir si il y a quelque chose de nouveau, le navigateur doit régulièrement faire des requêtes au serveur ou utiliser des gros hacks comme le long polling.</p>
<p>Les websockets (c&#8217;est un abus de langage, on devrait parler du protocole Websocket) ont été créés pour répondre à ces besoins : elles permettent d&#8217;ouvrir une connexion permanente entre le navigateur et le serveur. Ainsi, chaque requête est plus rapide, et plus légère. En prime, le serveur peut envoyer des requêtes au navigateur pour le prévenir qu&#8217;il y a du nouveau.</p>
<p>Ceci permet de faire tout ce que permettait de faire AJAX mais en plus rapide, et en plus léger. Et également d&#8217;envoyer des notifications (ce contenu a changé, un message est arrivé, l&#8217;autre joueur a fait cette action&#8230;) au navigateur au moment où l&#8217;événement se produit.</p>
<p>En gros, de faire des apps Web quasi temps réel.</p>
<p>Il existe d&#8217;autre technos pour faire cela : applets Java, flash, comet, server sent events&#8230;</p>
<p>Mais aucune n&#8217;ont décollé. Websocket est donc aujourd&#8217;hui la solution de facto.</p>
<h2>Caractéristiques</h2>
<p>Le protocole Websocket utilise l&#8217;abréviation <code>ws</code> et <code>wss</code> si SSL, les URLs vers des endpoints websocket ressemblent donc à : <code>ws://domaine.tld/chemin/vers/truc/</code>.</p>
<p>Intelligemment, il utilise un handshake compatible avec celui de HTTP, permettant à un serveur de gérer les deux sur les mêmes ports. Donc on peut faire du Websocket sur le port 80 et 443. Néanmoins, certains proxy se gourent quand ils voient du websocket non chiffré et gauffrent votre connexion en la traitant comme du HTTP. Donc si vous voulez une app solide, investissez dans un certif SSL.</p>
<p>Tout ça fonctionne à partir de IE10. Notez comme IE est devenu le standard de ce qui ce fait de moins bien à tel point que je n&#8217;ai même pas besoin de vous parler des autres, vous savez que ça marche. Il existe en plus des <a href="https://github.com/gimite/web-socket-js">plugins flash</a> pour simuler des websockets sur les navigateurs anciens, c&#8217;est à dire les encore plus vieux IE.</p>
<p>Par défaut, les websockets permettent de faire de requêtes crossdomain, contrairement à AJAX. Avec les nouvelles apps qui utilisent NodeJS en local (comme <a href="http://getpopcornti.me/">popcorntime</a>) on peut imaginer une nouvelle type d&#8217;attaque : une page web qui se connecte à un serveur websocket local de votre machine. Comme les websockets sont souvent utilisées pour du RPC, il y a du potentiel.</p>
<h2>Bon, ta gueule, et montre le code</h2>

<!-- iframe plugin v.2.9 wordpress.org/plugins/iframe/ -->
<iframe width="100%" height="300" src="http://jsfiddle.net/rpecs5f1/embedded/result,js" allowfullscreen="allowfullscreen" frameborder="0" scrolling="no" class="iframe-class"></iframe>

<p>Vous noterez que ce qui prend du temps dans l&#8217;exemple c&#8217;est la connexion, qu&#8217;on ne fait qu&#8217;une fois. Ensuite l&#8217;échange de données est super rapide.</p>
<p>Ceci est un exemple Javascript, mais un client websocket n&#8217;est pas forcément un navigateur. En fait, c&#8217;est très précisément le cas avec <a href="http://sametmax.com/presentation-de-wamp-round-2/">WAMP</a>, dont les clients peuvent être des programmes Python, Objective C, Java, C++, etc. L&#8217;avantage de WAMP, c&#8217;est qu&#8217;il automatise toute la machinerie pour découper la logique de son programme en divers fonctions et services, plutôt que d&#8217;avoir à tout faire à la main avec <code>send()</code> et <code>onmessage()</code>.</p>
<p>Dans tous les cas, il vous faudra un serveur qui supporte les Websockets pour l&#8217;utiliser. En Python, c&#8217;est Tornado ou Twisted (sur lequel est basé le serveur WAMP crossbar). En Javascript, c&#8217;est NodeJS. Quoi qu&#8217;il en soit, il vous faut un logiciel qui gère l&#8217;IO de manière <a href="http://sametmax.com/quelle-est-la-difference-entre-bloquer-et-en-cours-dexecution/">non bloquante</a>, car il y a de nombreuses connexions ouvertes en simultanées, si on veut que ça soit performant.</p>


feed_id: http://sametmax.com/?p=15623
title: IndexError : plateforme de Questions/Réponses pour Python en français 23
uri: IndexError-plateforme-de-Questions-Réponses-pour-Python-en-françai
url: http://sametmax.com/indexerror-plateforme-de-questionsreponses-pour-python-en-francais/
content:
<p>Quand des gens demandent de l&#8217;aide en comments, on les invite à aller plutôt sur des forums. Les commentaires sont pas pratiques pour ça.</p>
<h2>La nouvelle qu&#8217;elle est cool</h2>
<p>Aujourd&#8217;hui Max a installé un petit outil (PHP, mais bon, on va pas faire la fine bouche) genre mini-stackoverflow en beaucoup plus simple :</p>
<p><a href="http://indexerror.net/">IndexError</a></p>
<p>Vous pouvez maintenant poser vos questions techniques dessus, ou répondre à celles des autres. Le contenu est placé sous la même licence que le blog, en creative 3.0 unported.</p>
<p>Je vais traîner un peu dessus, et faire ce que je ne pouvais pas faire auparavant, donner un coup de main. Mais ne prenez pas ça pour une ligne directe en SAV gratuit avec Sam. On a plutôt envie qu&#8217;une petite communauté s&#8217;entraide, SamOS n&#8217;est pas scalable pour ce genre de charge. </p>
<h2>La clause en tout petit en bas du contrat</h2>
<p><strong>L&#8217;espace de discussions est uniquement fait pour parler de l&#8217;écosystème Python en français</strong>. Pas de cul, de Javascript ou autres trucs déviants ;)</p>
<p>Ça laisse quand même de la marge : Blender, Raspberry, Django, Pygame, Twisted, OpenCV, Scipy, Virtualenv, OpenStack, WAMP, ArcGIS&#8230; Y a du Python partout !</p>
<p>Le site est lent &#8211; et la raison est simple &#8211; on est hébergé sur la même petite instance que le blog pour des raisons de budget. Si il commence à y avoir un peu de monde, on migrera le truc sur quelque chose de plus gros. En attendant, <strong>on va croiser les doigts et serrer les fesses, espérant que ça nous explose pas à la tronche dès qu&#8217;il y a 3 clampins dessus</strong>.</p>
<p>Néanmoins, si ça arrive, ça va coûter des thunes. Contrairement au blog qui ne verra jamais un morceau d&#8217;AdSense par principe, il faudra bien trouver un moyen de payer ces frais. Donc en gros, si on commence à avoir du traf, y aura sûrement de la pub quelque part. J&#8217;annonce avant qu&#8217;on se fasse tomater la gueule sur scène&#8230; Ce truc n&#8217;est pas comme 0bin, ça fait des requêtes en masse, ça envoie de mails, ça consomme quoi.</p>
<p>On sépare donc bien la partie blog, qui reste un espace de liberté où on peut parler de sodomie sans se taper une pop under, et IndexError, quelque chose de plus classique. </p>


feed_id: http://sametmax.com/?p=13068
title: La notation de version SemVer 7
uri: La-notation-de-version-SemVer-1
url: http://sametmax.com/la-notation-de-version-semver/
content:
<p>Il y a des tas de manières d&#8217;indiquer la version d&#8217;un logiciel.</p>
<p>Ubuntu utilise l&#8217;année et le mois, à l&#8217;envers : la 14.04 indique une version sortie en avril 2014.</p>
<p>Avant la 1.2, angular utilisait les versions paires pour signifier la stabilité, et impaire pour l&#8217;instabilité.</p>
<p>Quelques projets utilisent des numéros de branche Git ou Svn.</p>
<p>Certains utilisent des noms du genre &#8220;kangourou-cosmique&#8221; pour marquer le coup.</p>
<p>Et d&#8217;autres mélangent plusieurs techniques.</p>
<p>En Python, la méthode recommandée est nommée <a href="http://semver.org/">SemVer</a>, pour Semantic Versioning.</p>
<h2>Explications</h2>
<p>Tout est basé sur la notion d&#8217;API publique. Si vous ne vous souvenez pas de ce qu&#8217;est une API publique, <a href="http://sametmax.com/quest-ce-quune-api/">c&#8217;est par ici</a>.</p>
<p>Une bibliothèque versionnée avec SemVer doit clairement documenter toute son API publique pour dire : voici les bouts de codes que vous pouvez utiliser sans risque.</p>
<p>Beaucoup de devs ne font pas, tout comme on fait souvent du REST non pur, on fait souvent du SemVer non pur, mais je vous le dis sinon des puristes viendront jouer de la moustache en commentaires.</p>
<p>Le principe est simple : votre versioning est noté <code>x.y.z</code>, <code>x</code>, <code>y</code> et <code>z</code> étant des entiers positifs. A moins que le nombre soit <code>0</code>, aucun nombre ne doit commencer par <code>0</code>.</p>
<p>Le <code>x</code> représente une version majeure, qui introduit au moins un changement incompatible dans l&#8217;API publique.</p>
<p>Le <code>y</code> représente une version mineure, qui introduit au moins une nouvelle fonctionnalité dans l&#8217;API publique.</p>
<p>Le <code>z</code> représente une correction de bug ou un changement dans l&#8217;API privée.</p>
<p>Et c&#8217;est tout.</p>
<h2>En pratique</h2>
<p>Si vous réparez un bug, <code>z</code> augmente de <code>1</code>.</p>
<p>Ex : <code>1.3.4</code> devient <code>1.3.5</code></p>
<p>Si vous introduisez un nouveau paramètre optionnel, une fonction outil indépendante, un nouvel attribut public, <code>y</code> augmente de <code>1</code>, et <code>z</code> est remis à 0 :</p>
<p>Ex : <code>1.3.4</code> devient <code>1.4.0</code></p>
<p>Si une fonction retourne maintenant ne serait-ce qu&#8217;un tuple au lieu de précédemment une liste, <code>x</code> augmente de <code>1</code>, <code>y</code> et <code>z</code> sont remis à 0 :</p>
<p>Ex : <code>1.3.4</code> devient <code>2.0.0</code></p>
<h2>FAQ</h2>
<h3>Le numéro de version va monter très vite non ?</h3>
<p>On ne change le numéro de version que pour une version publiée. Si vous faites plein de petits changements mais que vous ne déclarez pas ce nouveau code comme la dernière version officielle, pas besoin de changer de version : vous êtes encore en développement.</p>
<p>N&#8217;oubliez pas aussi que c&#8217;est VOTRE job de vous assurez que votre programme reste compatible. Faites des adapters, des alias, introduisez les fonctionnalités de manière optionnelle, depréciation à l&#8217;avance&#8230; Il y a des moyens de faire ça proprement.</p>
<h3>C&#8217;est quand même over chiant pour une lib qui vient de sortir et que personne n&#8217;utilise, non ?</h3>
<p>Jusqu&#8217;à la version <code>1.0.0</code>, le SemVer ne s&#8217;applique pas. En <code>0.y.z</code>, on peut faire du freestyle.</p>
<h3>Mais si je suis en beta ?</h3>
<p>On peut signaler des informations supplémentaires en mettant un tiret après son versioning. Le style est libre mais la convention est généralement <code>x.y.z-status</code>. Ex : <code>1.3.3-alpha</code>, <code>1.3.3-beta</code>, <code>1.3.3-rc1</code>, etc.</p>
<h3>Attend, je fais une release parfaitement compatible, mais avec une fonction publique qui ne retourne plus <code>1</code> mais <code>True</code>, je vais pas bumper pour ça quand même ?</h3>
<p>Si. Si vous ne voulez pas le faire, mettez le dans une branche à part, et attendez une release plus grosse pour introduire ce changement.</p>
<h3>J&#8217;ai une correction de bug qui introduit une changement incompatible dans l&#8217;API publique, je fais quoi ?</h3>
<p>On bump. Ça n&#8217;arrive pas si souvent que ça qu&#8217;un bug change l&#8217;API publique, faut pas charrier.</p>
<h3>Ouais, genre tu le fais&#8230;</h3>
<p>Non, je ne fais pas du SemVer pur. Mais sur une lib qui est très utilisée, c&#8217;est un système indispensable. Si j&#8217;avais la responsabilité de pondre Django, ouais, je ferais du SemVer pur.</p>
<h3>Ok, je l&#8217;ai fais mais j&#8217;ai pas l&#8217;impression d&#8217;y gagner quoi que ce soit.</h3>
<p>Le bénéfice n&#8217;est pas pour l&#8217;auteur, mais pour les utilisateurs. Si un autre utilisateur à votre lib comme dépendance, il peut déclarer dans son fichier setup.py:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">requires<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'votrelib&gt;=1.3.1&lt;2.0.0'</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Ainsi il est certain que ça ne pétera pas si vous faites votre boulot correctement car la lib installée par pip sera toujours dans une version entre la 1.3.1 qu&#8217;il sait compatible, jusqu&#8217;à la 2.0.0 qui sera incompatible.</p>


feed_id: http://sametmax.com/?p=15653
title: Les articles les plus importants sur Python 6
uri: Les-articles-les-plus-importants-sur-Python-Recently-updated
url: http://sametmax.com/les-articles-les-plus-importants-sur-python/
content:
<p>J&#8217;ai beau régulièrement pointer vers la section <a href="http://sametmax.com/cours-et-tutos/">Cours et tutos</a>, je sens bien que les gens n&#8217;en bénéficient pas autant qu&#8217;ils le devraient.</p>
<p>Une des raisons est la quantité d&#8217;info à lire. </p>
<p>Ok, voici donc une sélection d&#8217;articles, qui ne sont pas forcément orientés débutants. Ce sont les trucs à maîtriser. Pas tout de suite. Pas tout d&#8217;un coup. Mais au final, un programmeur Python doit savoir ça.</p>
<ul>
<li><a href="http://sametmax.com/message-de-service-aux-debutants-en-python/">Message de service aux débutant</a></li>
<li><a href="http://sametmax.com/votre-python-aime-les-pip/">Installer une lib avec pip</a></li>
<li><a href="http://sametmax.com/les-environnement-virtuels-python-virtualenv-et-virtualenvwrapper/">Virtualenv</a></li>
<li><a href="http://sametmax.com/python-love-les-listes-en-intention-partie/">Les listes en intensions</a></li>
<li><a href="http://sametmax.com/les-trucmuchables-en-python/">Les trucmuchables</a></li>
<li><a href="http://sametmax.com/ordonner-en-python/">Ordonner en Python</a></li>
<li><a href="http://sametmax.com/debugger-en-python-les-bases-de-pdb/">Les bases de pdb</a></li>
<li><a href="http://sametmax.com/si-vous-ne-savez-pas-ce-que-contient-une-variable-vous-ne-comprenez-pas-le-programme/">Si vous ne savez pas ce que contient une variable, vous ne comprenez pas le programme.</a></li>
<li><a href="http://sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/">L&#8217;encoding en python</a></li>
<li><a href="http://sametmax.com/comment-utiliser-yield-et-les-generateurs-en-python/">Les générateurs et le mot clé yield</a></li>
<li><a href="http://sametmax.com/operateur-splat-ou-etoile-en-python/">L’opérateur splat (l’étoile: *)</a></li>
<li><a href="http://sametmax.com/comprendre-les-decorateurs-python-pas-a-pas-partie-1/">Les décorateurs</a></li>
<li><a href="http://sametmax.com/les-context-managers-et-le-mot-cle-with-en-python/">Les context managers et le mot clé with</a></li>
<li><a href="http://sametmax.com/le-guide-ultime-et-definitif-sur-la-programmation-orientee-objet-en-python-a-lusage-des-debutants-qui-sont-rassures-par-les-textes-detailles-qui-prennent-le-temps-de-tout-expliquer-partie-1/">La programmation orientée objet</a></li>
<li><a href="http://sametmax.com/tres-grand-listing-des-libs-standard-partie-les-plus-utiles-en-python/">(Très) Grand listing des libs standards les plus utiles</a></li>
</ul>


feed_id: http://sametmax.com/?p=15659
title: S’assurer que SELinux ne bloque pas un programme 7
uri: S-assurer-que-SELinux-ne-bloque-pas-un-programme-3
url: http://sametmax.com/sassurer-que-selinux-ne-bloque-pas-un-programme/
content:
<p>Les distros Linux récentes viennent souvent avec des surcouches de protections type policykit, apparmor, SELinux, etc.</p>
<p>Tout ça est bien loin de la simplicité de la notion user/group et leurs permissions, et peut mener à un arrachage de cheveux en règle. </p>
<p>Cette après midi par exemple, on avait notre backend qui ne répondait pas sur le serveur tout neuf. On a changé toutes les permissions, passé de <code>sock://</code> à <code>http://</code>, tweaké les fichiers de settings de iptables, varnish, nginx, gunicorn, supervisor, django&#8230; Puis en dernier recours, on a viré toutes les couches une par une, desinstaller les programmes, réinstaller à neuf, reset les fichiers de config en valeur par défaut, créé des fichiers de config minimaux pour toute la stack, nada. La journée frustrante et foutue en l&#8217;air.</p>
<p>On a quand même isolé le point de blocage sur varnish, et après avoir fait tous les tests possibles et des sacrifices humains, Max a eu l&#8217;intuition SELinux.</p>
<p>Voici maintenant ce qui se passe généralement dans cette situation.</p>
<p>Dans un élan de colère, l&#8217;utilisateur impatient fera un rapide test pour savoir si SELinux le protège comme les USA ont protégé les irakiens :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">&gt;/</span>selinux<span style="color: #000000; font-weight: bold;">/</span>enforce</pre></td></tr></table></div>

<p>Ça désactive tout le bouzin jusqu&#8217;au prochain reboot, mettre <code>1</code> inversant la tendance.</p>
<p>Lançant son programme et voyant que ça marche, notre dev échaudé se fend de l&#8217;équivalent du <code>chmod 777 -R</code> pour SELinux, à savoir éditer le fichier de config (<code>/etc/sysconfig/selinux</code> sur Centos) et changer rageusement <code>SELINUX=enforcing</code> pour <code>SELINUX=disabled</code>. Reboot and forget.</p>
<p>Une solution radicale et efficace, certes, mais qui laisse quand même un petit poids sur le conscience : diantre, il y a sûrement un moyen propre d&#8217;essuyer toute cette merde. Où sont les 3 coquillages ?</p>
<p>La solution est dans un petit programme appelé <code>audit2allow</code>, qui fait parti d&#8217;un package plus gros qu&#8217;il vous faudra trouver pour votre OS. Sous CentOs, puisque c&#8217;était notre config ce jour là, on a du faire un petit :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">yum install</span> policycoreutils-python</pre></td></tr></table></div>

<p>Ensuite, on lance notre audit :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">audit2allow <span style="color: #660033;">-a</span> <span style="color: #660033;">-w</span></pre></td></tr></table></div>

<p>Et après un peu de moulinage, il va vous sortir tout un listing de blocage, et quoi faire pour s&#8217;en sortir. Un petit <code>grep votre_prog</code> sur la sortie et vous obtenez ceci :</p>
<pre>type=AVC msg=audit(1331500393.450:25): avc:  denied  { name_connect } for  pid=1276 comm="varnishd" dest=81 scontext=unconfined_u:system_r:varnishd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket
        Was caused by:
        One of the following booleans was set incorrectly.
        Description:
        Allow varnishd to connect to all ports, not just HTTP.

        Allow access by executing:
        # setsebool -P varnishd_connect_any 1
        Description:
        Allow system to run with NIS

        Allow access by executing:
        # setsebool -P allow_ypbind 1</pre>
<p>Nous, c&#8217;était varnish qui était bloqué, comme le confirme le discret <strong>denied</strong> dans ce gros blog d&#8217;informations illisibles. A croire que les gars de SELinux ont tout fait pour créer la techno la moins user friendly possible. Je pense que la ligne ne commence pas par &#8220;AVC&#8221; pour rien, chaque fois que SELinux bloque un truc, un devops stagiaire meurt quelque part.</p>
<p>Il suffit ensuite de suivre docilement les instructions. Pour ce cas, on rentre avec les droits admin la commande :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">setsebool <span style="color: #660033;">-P</span> varnishd_connect_any <span style="color: #000000;">1</span></pre></td></tr></table></div>

<p>Et on est bon. </p>
<p>Enfin, jusqu&#8217;à la prochaine après midi de debug incompréhensible qui vous fera revenir à SELinux. Max est beaucoup tenté par la solution 1 pour éviter une nouvelle galère. </p>


feed_id: http://sametmax.com/?p=15665
title: Les managers le détestent : faites tourner WAMP dans Django avec cette astuce insolite 9
uri: Les-managers-le-détestent-faites-tourner-WAMP-dans-Django-avec-cett
url:
http://sametmax.com/les-managers-le-detestent-faites-tourner-wamp-dans-django-avec-cette-astuce-insolite/

content:
<p>Il existe une lib appelée <a href="https://pypi.python.org/pypi/crochet">crochet</a> qui permet de faire marcher des API de twisted entre deux bouts de code bloquants. Certes, ça ne marche qu&#8217;en 2.7 et c&#8217;est pas hyper performant, mais on peut faire des trucs mignons du genre cette démo qui <a href="https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/wamp/app/crochet/example1">mélange flask et WAMP</a>.</p>
<p>C&#8217;est du pur Python, pas de process externe à gérer, c&#8217;est presque simple.</p>
<p>Bref, si on veut utiliser WAMP avec une app synchrone comme flask, c&#8217;est un bon moyen de s&#8217;y mettre. On aura jamais des perfs fantastiques, mais on peut pusher vers le browser.</p>
<p>Du coup je me suis demandé si on pouvait faire ça avec Django.</p>
<p>Évidement, ça a été un peu plus compliqué car par défaut <code>runserver</code> lance plusieurs workers et fait un peu de magie avec les threads. Mais après un peu de bidouillage, ça marche !</p>
<p>On peut utiliser WAMP, <code>directement</code> dans Django.</p>
<h2>Suivez le guide</h2>
<p>D&#8217;abord, on installe tout le bouzin (python 2.7, souvenez-vous) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> crossbar crochet django</pre></td></tr></table></div>

<p>Il vous faudra un Django 1.7, le tout dernier, car il possède <a href="https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready">une fonctionnalité</a> qui nous permet de lancer du code quand tout le framework est chargé.</p>
<p>Vous vous faites votre projet comme d&#8217;hab, et vous ouvrez le fichier de settings et au lieu de mettre votre app dans <code>INSTALLED_APPS</code>, vous rajoutez ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">INSTALLED_APPS <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">'...'</span><span style="color: #66cc66;">,</span>
    <span style="color: #483d8b;">'votreapp.app.VotreAppConfig'</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Puis dans le module de votre app, vous créez un fichier app.py, qui va contenir ça:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> crochet
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">apps</span> <span style="color: #ff7700;font-weight:bold;">import</span> AppConfig
&nbsp;
<span style="color: #808080; font-style: italic;"># On charge l'objet contenant la session WAMP définie dans la vue</span>
<span style="color: #ff7700;font-weight:bold;">from</span> votreapp.<span style="color: black;">views</span> <span style="color: #ff7700;font-weight:bold;">import</span> wapp
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> VotreAppConfig<span style="color: black;">&#40;</span>AppConfig<span style="color: black;">&#41;</span>:
    name <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'votreapp'</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> ready<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># On dit a crochet de faire tourner notre app wamp dans sa popote qui</span>
        <span style="color: #808080; font-style: italic;"># isole le reactor de Twisted</span>
        <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> start_wamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
           <span style="color: #808080; font-style: italic;"># On démarre la session WAMP en se connectant au serveur</span>
           <span style="color: #808080; font-style: italic;"># publique de test</span>
           wapp.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;wws://demo.crossbar.io/ws&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;realm1&quot;</span><span style="color: #66cc66;">,</span> start_reactor<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
        start_wamp<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On passe à urls.py dans lequel on se rajoute des vues de démo :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^ping/'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'votreapp.views.ping'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'votreapp.views.index'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Puis dans notre fichier views.py, on met :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> uuid
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;">import</span> render
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> crochet
&nbsp;
<span style="color: #808080; font-style: italic;"># Crochet se démerde pour faire tourner le reactor twisted de</span>
<span style="color: #808080; font-style: italic;"># manière invisible. A lancer avant d'importer autobahn</span>
crochet.<span style="color: black;">setup</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> autobahn.<span style="color: black;">twisted</span>.<span style="color: black;">wamp</span> <span style="color: #ff7700;font-weight:bold;">import</span> Application
&nbsp;
<span style="color: #808080; font-style: italic;"># un objet qui contient une session WAMP</span>
wapp <span style="color: #66cc66;">=</span> Application<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># On enrobe les primitives de WAMP pour les rendre synchrones</span>
<span style="color: #66cc66;">@</span>crochet.<span style="color: black;">wait_for</span><span style="color: black;">&#40;</span>timeout<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> publish<span style="color: black;">&#40;</span>topic<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
   <span style="color: #ff7700;font-weight:bold;">return</span> wapp.<span style="color: black;">session</span>.<span style="color: black;">publish</span><span style="color: black;">&#40;</span>topic<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">@</span>crochet.<span style="color: black;">wait_for</span><span style="color: black;">&#40;</span>timeout<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> call<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
   <span style="color: #ff7700;font-weight:bold;">return</span> wapp.<span style="color: black;">session</span>.<span style="color: black;">call</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> register<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> decorator<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
        wapp.<span style="color: black;">register</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> decorator
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> subscribe<span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #66cc66;">@</span>crochet.<span style="color: black;">run_in_reactor</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> decorator<span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>:
        wapp.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span>func<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> decorator
&nbsp;
<span style="color: #808080; font-style: italic;"># Et hop, on peut utiliser nos outils WAMP !</span>
&nbsp;
<span style="color: #66cc66;">@</span>register<span style="color: black;">&#40;</span><span style="color: #483d8b;">'uuid'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> get_uuid<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> uuid.<span style="color: black;">uuid4</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">hex</span>
&nbsp;
<span style="color: #66cc66;">@</span>subscribe<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> onping<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Et à côté, quelques vues django normales</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> index<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># pub et RPC en action côté Python</span>
    publish<span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> call<span style="color: black;">&#40;</span><span style="color: #483d8b;">'uuid'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'index.html'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> ping<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'ping.html'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Après, un peu de templating pour que ça marche&#8230;</p>
<p>Index.html :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html" style="font-family:monospace;">{% load staticfiles %}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;title&gt;
       UUID
    &lt;/title&gt;
&nbsp;
    &lt;script src=&quot;{% static 'autobahn.min.js' %}&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      var connection = new autobahn.Connection({
         url: &quot;ws://localhost:8080/ws&quot;,
         realm: &quot;realm1&quot;
      });
&nbsp;
     connection.onopen = function (session) {
&nbsp;
        session.call(&quot;uuid&quot;).then(function (uuid) {
          var p = document.getElementById('uuid');
          p.innerHTML = uuid;
        });
     };
&nbsp;
     connection.open();
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h2&gt;UUID&lt;/h2&gt;
&lt;p id=&quot;uuid&quot;&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>ping.html :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#123;</span>% load staticfiles %<span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&lt;!</span>DOCTYPE html<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>html<span style="color: #66cc66;">&gt;</span>
  <span style="color: #66cc66;">&lt;</span>head<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>meta charset<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;utf-8&quot;</span> /<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>title<span style="color: #66cc66;">&gt;</span>
       Ping
    <span style="color: #66cc66;">&lt;</span>/title<span style="color: #66cc66;">&gt;</span>
&nbsp;
    <span style="color: #66cc66;">&lt;</span>script src<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;{% static 'autobahn.min.js' %}&quot;</span><span style="color: #66cc66;">&gt;&lt;</span>/script<span style="color: #66cc66;">&gt;</span>
    <span style="color: #66cc66;">&lt;</span>script <span style="color: #008000;">type</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;text/javascript&quot;</span><span style="color: #66cc66;">&gt;</span>
      var connection <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">new</span> autobahn.<span style="color: black;">Connection</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
         url: <span style="color: #483d8b;">&quot;ws://localhost:8080/ws&quot;</span><span style="color: #66cc66;">,</span>
         realm: <span style="color: #483d8b;">&quot;realm1&quot;</span>
      <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
     connection.<span style="color: black;">onopen</span> <span style="color: #66cc66;">=</span> function <span style="color: black;">&#40;</span>session<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
&nbsp;
        session.<span style="color: black;">subscribe</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ping&quot;</span><span style="color: #66cc66;">,</span> function <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
          var ul <span style="color: #66cc66;">=</span> document.<span style="color: black;">getElementById</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ping'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
          var li <span style="color: #66cc66;">=</span> document.<span style="color: black;">createElement</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'li'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
          li.<span style="color: black;">innerHTML</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'Ping !'</span>
          ul.<span style="color: black;">appendChild</span><span style="color: black;">&#40;</span>li<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
     <span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span>
&nbsp;
     connection.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
    <span style="color: #66cc66;">&lt;</span>/script<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/head<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>h2<span style="color: #66cc66;">&gt;</span>Ping me <span style="color: #66cc66;">!&lt;</span>/h2<span style="color: #66cc66;">&gt;</span>
&nbsp;
<span style="color: #66cc66;">&lt;</span>ul <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;ping&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/ul<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/body<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>/html<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>On ouvre la console, on lance son routeur :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">    crossbar init
    crossbar start</pre></td></tr></table></div>

<p>On lance dans une autre console son serveur Django :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>manage.py runserver</pre></td></tr></table></div>

<p>Et si on navigue sur <code>http://127.0.0.1:8000</code>, on récupère un UUID tout frais via RCP.</p>
<p>On peut aussi voir dans le shell que ça marche côté Python :</p>
<pre>94cfccf0899d4c42950788fa655b65ed
ping</pre>
<p>D’ailleurs un fichier nommé &#8220;test&#8221; est créé à la racine du projet.</p>
<p>Et si on navigue sur <code>http://127.0.0.1:8000/ping/</code> et qu&#8217;on refresh <code>http://127.0.0.1:8000</code> plusieurs fois, on voit la page se mettre à jour.</p>
<p>Achievement unlock : use WAMP and Django code in the same file.</p>
<h2>A partir de là</h2>
<p>Il y a plein de choses à faire.</p>
<p>On pourrait faire une lib qui wrap tout ça pour pas à avoir à le mettre dans son fichier de vue et qui utilise settings.py pour la configuration.</p>
<p>Il faut tester ça avec des setups plus gros pour voir comment ça se comporte avec gunicorn, plusieurs workers, le logging de Django, etc. Je suis à peu près sûr que les callbacks vont être registrés plusieurs fois et ça devrait faire des erreurs dans les logs (rien de grave ceci dit).</p>
<p>On pourrait aussi adapter le RPC pour qu&#8217;il utilise les cookies d&#8217;authentification Django, et pouvoir les protéger avec @login_required.</p>
<p>Mais un monde d&#8217;opportunités s&#8217;offrent à vous à partir de là.</p>
<p>Moi, ça fait 6 h que je taffe dessus, je vais me pieuter.</p>
<hr />
<p><a href="https://github.com/sametmax/codes-des-articles/tree/master/2015/janvier/wamp_et_django">Télécharger le code de l&#8217;article</a></p>


feed_id: http://sametmax.com/?p=10493
title: Black awk down 8
uri: Black-awk-down-5-Recently-updated
url: http://sametmax.com/black-awk-down/
content:
<blockquote><p>Ceci est un post invité de <a href="http://sametmax.com/author/foX" target="_blank">foX </a>posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">creative common 3.0 unported</a>.</p></blockquote>
<h2>Introduction (sans douleur)</h2>
<p>Qui n&#8217;a jamais rêvé d&#8217;avoir un shell Unix un peu plus pythonic ? Les oneliners en <a href="http://fr.wikipedia.org/wiki/Stream_Editor" title="sed">sed</a> et <a href="http://fr.wikipedia.org/wiki/Awk" title="Awk">Awk</a> bien chiadés, c&#8217;est l&#8217;apanage des grands barbus en sandales et ça déchire, mais ça reste cryptique et la manipulation de liste et de chaînes de caractères est tout de même limitée. On peut dégainer perl en one line, comme ça c&#8217;est encore plus puissant mais moins lisible&#8230;</p>
<p>Et python dans tout ça ? En oneliner, ça craint, car le principe d&#8217;indentation ne facilite pas les choses et on finit avec une imbrication de bazar de parenthèses illisible.</p>
<p>La solution ? Pour se faire plaisir : une bonne pyp. Le bidule s&#8217;installe avec&#8230; pip (c&#8217;est une méta pipe).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> pyp</pre></td></tr></table></div>

<p>pyp (<a href="http://code.google.com/p/pyp/" title="pyp">Python Power at the Prompt</a>) va enchanter votre shell unix et vous envoyer au 7ème ciel. Petit tour d&#8217;horizon de la merveille.</p>
<h2>Pyp et les strings</h2>
<p>C&#8217;est la base quand on bricole des oneliners en shell, tripoter des strings.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">*</span>JPG <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;'mv', p, p.replace('JPG', 'jpg')&quot;</span></pre></td></tr></table></div>

<p>Revoyons l&#8217;action au ralenti : </p>
<ul>
<li>ls *JPG va nous lister tous les fichiers qui finissent par JPG dans le dossier courant.</li>
<li>Ensuite on envoie cela dans pyp avec un pipe Unix. Celui-ci va composer une ligne de commande qui est la concaténation d&#8217;une commande unix (mv pour renommer un fichier), ce qu&#8217;on aura reçu en entrée (qui s&#8217;appelle par convention &#8220;p&#8221;) et une version modifiée de p où l&#8217;on remplace JPG par jpg.</li>
</ul>
<p>On voit ici que l&#8217;on utilise la méthode replace de la classe str python. On peut utiliser n&#8217;importe quelle méthode de str : lower, upper, title, strip(tease), count etc. Avec des petits bonus comme refindall(re) :-)</p>
<p>Ça donne quoi ma brave dame ? Et bien si on avait des fichiers appelés porn1.JPG et ass.JPG notre jolie commande renverrait :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mv</span> porn1.JPG porn1.jpg
<span style="color: #c20cb9; font-weight: bold;">mv</span> ass.JPG ass.jpg</pre></td></tr></table></div>

<p>Ok, bien gentil me direz-vous, mais qu&#8217;en fait-on ? Et bien ou l&#8217;on pipe ça dans le shell ( | sh) ou alors on passe l&#8217;argument -x (ou &#8211;execute) à pyp ou directement exécuter le résultat.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">*</span>JPG <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;'mv', p, p.replace('JPG', 'jpg')&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sh</span>
<span style="color: #666666; font-style: italic;"># ou bien</span>
<span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">*</span>JPG <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #660033;">-x</span> <span style="color: #ff0000;">&quot;'mv', p, p.replace('JPG', 'jpg')&quot;</span></pre></td></tr></table></div>

<p>Pourquoi on aime bien python ? Car il slice le bread comme un chef. Pyp aussi, oeuf corse, quelques exemples :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;sam-et-max&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;p.split('-')[2]&quot;</span>
<span style="color: #666666; font-style: italic;"># max</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># La même chose en plus court. Le m, comme minus, sous-entend qu'on split sur &quot;-&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;sam-et-max&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;m[2]&quot;</span>
<span style="color: #666666; font-style: italic;"># max</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;sam-et-max&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;m[0], m[2]&quot;</span>
<span style="color: #666666; font-style: italic;"># sam max</span></pre></td></tr></table></div>

<p>Comme vous avez vu, il y a un petit raccourci sympa avec m (comme minus) au lieu de p. C&#8217;est pas fini, vous en avez d&#8217;autres : d (dot) pour un point, w (whitespace) pour une espace, u pour underscore, s pour slash&#8230; Ils ont pensé à tout.</p>
<h2>Des pyp à la chaîne</h2>
<p>On tout de suite envie de remettre le couvert avec une autre pyp. C&#8217;est possible et même encouragé. Le symbole utilisé est le pipe unix | dans une commande pyp. Ce n&#8217;est donc pas un pipe du shell mais un pipe interne de pyp. Vous suivez ? Un petit exemple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;sam et max&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[0] | 'avant : ', o, 'après :', p&quot;</span>
<span style="color: #666666; font-style: italic;"># avant :  sam et max après : sam</span></pre></td></tr></table></div>

<p>Le p représente toujours le paramètre courant. Donc dans la seconde partie du pipe, c&#8217;est le premier élément de la liste issu du split de la chaîne &#8220;sam et max&#8221; sur l&#8217;espace (w comme whitespace). Vous suivez toujours ? Oui, bon. Et donc le o ? Et bien c&#8217;est le paramètre d&#8217;origine non modifié. Et il y a h (comme history ou comme hâlibi !) pour avoir le paramètre p à toutes les étapes de la chaîne de pipe&#8230; Beaucoup de puissance on vous dit !</p>
<p>On peut aussi rouler^w faire des join facilement avec les mêmes raccourcis. Par exemple on split sur les espaces puis join sur slash :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;sam et max aiment le lourd en fin de soirée&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[:6]|s&quot;</span>
<span style="color: #666666; font-style: italic;"># sam/et/max/aiment/le/lourd</span></pre></td></tr></table></div>

<h2>Une liste de pyp avec une belle pp</h2>
<p>S&#8217;il y a un bien un truc qui envoie du bois avec python, c&#8217;est la gestion des listes. Pyp n&#8217;est pas en reste. C&#8217;est pp qui contient les listes. En avant :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;pp[3]&quot;</span>
<span style="color: #666666; font-style: italic;"># Affiche le troisième fichier</span></pre></td></tr></table></div>

<p>On peut utiliser toutes les méthodes standards de la classe list (sort, count etc.) plus quelques bonus :</p>
<p># Équivalent de | sort | uniq</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;pp.uniq()&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Additionne tous les PID des process de machine.</span>
<span style="color: #666666; font-style: italic;"># Ça ne sert à rien, mais c'est un exemple hein ?</span>
<span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-ef</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[1] | int(p) | sum(pp)&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Voilà qui est plus utile. </span>
<span style="color: #666666; font-style: italic;"># Au passage, on note que la ligne d'en-tête est ignoré et ne fait pas planter pyp.</span>
<span style="color: #666666; font-style: italic;"># Malin le lapin.</span>
<span style="color: #c20cb9; font-weight: bold;">df</span> <span style="color: #660033;">-m</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[1] | int(p) | sum(pp)&quot;</span></pre></td></tr></table></div>

<h2>pyp au naturel</h2>
<p>Pour compléter les fonctions python, pyp propose quelques fonctions maisons tout à fait sympathiques. Florilège :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Sam Bill Max&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;p.kill('Bill')&quot;</span>  <span style="color: #666666; font-style: italic;"># quand c'est pas bill, c'est kenny...</span>
<span style="color: #666666; font-style: italic;"># Sam  Max</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000;">124</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;(int(p)/2+30)&quot;</span>
<span style="color: #666666; font-style: italic;"># 91</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ls</span>  <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;n, p&quot;</span>
<span style="color: #666666; font-style: italic;"># Liste des fichiers avec un numéro croissant devant</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>fox<span style="color: #000000; font-weight: bold;">/</span>video<span style="color: #000000; font-weight: bold;">/</span>gangbang.avi  <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;'Dir='+p.dir, '<span style="color: #000099; font-weight: bold;">\n</span>File='+p.file, '<span style="color: #000099; font-weight: bold;">\n</span>Ext='+p.ext&quot;</span> <span style="color: #666666; font-style: italic;"># basename, dirname et ses amis</span>
<span style="color: #666666; font-style: italic;"># Dir=/home/fox/video </span>
<span style="color: #666666; font-style: italic;"># File=gangbang.avi </span>
<span style="color: #666666; font-style: italic;"># Ext=avi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># On définit le séparateur de liste comme l'espace, </span>
<span style="color: #666666; font-style: italic;"># puis on regroupe la liste par deux élément</span>
<span style="color: #666666; font-style: italic;"># et enfin on fait un join sur le caractère tiret (minus)</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;1 2 3 4 5 6&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;pp.delimit(' ') | pp.divide(2) | m&quot;</span>
<span style="color: #666666; font-style: italic;"># 1-2</span>
<span style="color: #666666; font-style: italic;"># 3-4</span>
<span style="color: #666666; font-style: italic;"># 5-6</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-ef</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[1] | int(p) | max(pp)&quot;</span> 
<span style="color: #666666; font-style: italic;"># (le PID le plus grand)</span></pre></td></tr></table></div>

<h2>pyp en intention ou intention de pyp ?</h2>
<p>Il ne faut pas se gêner, on peut utiliser les excellentes <a href="http://sametmax.com/python-love-les-listes-en-intention-partie/" title="Listes en intention">listes en intention</a> de Python.  Voici tous les PID impaires :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-ef</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[1] | int(p) | [i for i in pp if i%2] | p &quot;</span></pre></td></tr></table></div>

<h2>L&#8217;industrie de la pyp c&#8217;est un truc de macro</h2>
<p>Les bonnes choses, ça se garde, alors voilà :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-ef</span> <span style="color: #000000; font-weight: bold;">|</span> pyp <span style="color: #ff0000;">&quot;w[1] | int(p) | [i for i in pp if i%2] | p &quot;</span> <span style="color: #660033;">-s</span> odd  <span style="color: #666666; font-style: italic;"># on enregistre la macro 'odd'</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ps</span> ef <span style="color: #000000; font-weight: bold;">|</span> pyp odd <span style="color: #666666; font-style: italic;"># c'est aussi simple que cela ;-)</span></pre></td></tr></table></div>

<h2>pyp sur grand écran</h2>
<p>Cette petite pépite est développée par Sony Pictures Imageworks pour ses besoins internes. Le développement n&#8217;est pas très collaboratif (un commit par release&#8230;) mais reste ouvert aux contributions externes. C&#8217;est sous une licence de type BSD.<br />
Les loulous ont fait une jolie vidéo de tutorial très bling bling. C&#8217;est l&#8217;avantage de bosser dans le milieu : </p>
<p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/eWtVWF0JSJA?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p>
<h2>Et bien plus encore&#8230;</h2>
<p>Cet outil merveilleux possède encore des fonctionnalités qui vont vous le faire adorer comme son mode interactif avec une coloration syntaxique sympathique, la gestion de l&#8217;historique dans le pipe et beaucoup d&#8217;autres. Adieu sed, awk, uniq, sort et con sort, vous étiez mes premiers amours, mais pyp vous chasse dehors.</p>
<p>Ce n&#8217;est pas la seule ni la première tentative de faire la peau d&#8217;awk avec python. Sam avait déjà écrit <a href="http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/" title="une pyped pour Sam">un article </a>sur une autre solution aussi appelée pyped.</p>
<h2> C&#8217;est donc parfait ? </h2>
<p>Oui, bien entendu. Aucun défaut, aucun bug. Ok&#8230; voici les limites : </p>
<ul>
<ol>Perf de daube. Sur des petits volumes (quelques milliers de lignes) ça le fait. Au delà, ça rame. Quelques patch sont proposés pour diviser par trois le temps de traitement :-)</ol>
<ol>Conso mémoire obcène. Idem, pour des petits volumes on s&#8217;en fout, mais sinon ça peut rapidement chiffrer. Pourquoi ? Le machin ne fonctionne pas en stream, tout est gardé en mémoire et à chaque étape de transformation (pour permettre d&#8217;accéder à l&#8217;historique).</ol>
<ol>C&#8217;est installé sur votre pc, mais pas partout, contrairement à ce bon vieux awk. </ol>
</ul>
<p>Amusez vous bien, celui qui fait la plus jolie commande pyp dans les commentaires aura le droit à un bisous.</p>


feed_id: http://sametmax.com/?p=15682
title: Conclusions de la migration 10
uri: Conclusions-de-la-migration
url: http://sametmax.com/conclusions-de-la-migration/
content:
<p>La migration de serveur est terminée. Le blog, le <a href="http://multiboards.net">multiboards</a>, <a href="http://indexerror.net">IndexError</a> et <a href="http://0bin.net">0bin</a> on été rétablis. On en a profité pour remettre sur pied <a href="http://allthatcounts.net">AllThatCounts</a> qui avait été délaissé durant le dernier crash.</p>
<p>On quitte donc <a href="https://www.leaseweb.com/">LeaseWeb</a>, qui nous a forcé à migré 3 fois avec ses machines qui ont planté. En plus deux fois la partition <code>/tmp</code> était corrompue, ce qui rend le backup particulièrement compliqué. On notera que leur SAV nous posait des questions du genre &#8220;si vous installez ça, et lancez cette commande, ça donne quoi ?&#8221;, alors qu&#8217;on leur a bien notifié qu&#8217;on avait un disque monté en lecture seul du fait du FS en vrac&#8230;</p>
<p>On est passé chez <a href="http://www.cinfu.com/vps/">Cinfu</a>, car on peut les payer en Bitcoin. Livraison du serveur rapide, installation sans histoire, et finalement une migration beaucoup moins chiante que la dernière fois car on a fait les gros bourrins : <code>rsync</code> + <code>mysqldump</code> bien large. Ce qui a pris le plus de temps c&#8217;était de résoudre les centaines de problèmes de permissions que ça a créé, les trucs que ça aurait pas du écraser, etc.</p>
<p>On avait + de 100000 spams dans la poubelle des commentaires, qui prenaient 300 Mo des 400 mo de la taille totale de la BDD du blog. Un petit :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> wp_comments <span style="color: #993333; font-weight: bold;">WHERE</span> comment_approved <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'trash'</span>;</pre></td></tr></table></div>

<p>A accéléré la migration vu qu&#8217;on a du transférer la base 3 fois et la réimporter autant à cause d&#8217;erreurs diverses. Note à nous-même : arrêter de mettre des <code>.bak</code> dans <code>/tmp</code> parce que c&#8217;est &#8220;juste pour 5 minutes&#8221;. Après on se fait avoir comme des débutants au reboot. </p>
<p>C&#8217;est là qu&#8217;on voit qu&#8217;on est dev, et pas admin.</p>
<p>Rajouter dans wp-config.php :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'EMPTY_TRASH_DAYS'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Nous évitera d&#8217;avoir à repenser à tout ça. C&#8217;est con mais faut le savoir.</p>
<p>J&#8217;en profite pour témoigner mon amour immodéré pour <a href="https://mosh.mit.edu/">mosh</a>. Parce que faire tout ça sur une connexion thai avec 300ms de ping minimum et une coupure toutes les 10 minutes, avec SSH, c&#8217;est juste un enfer.</p>
<p>Sous Centos, faut installer les repos <code>EPEL</code> et <code>yum install mosh</code> derrière.</p>
<p>Sous Ubuntu, fait installer le ppa <code>ppa:keithw/mosh</code> et <code>apt-get install mosh</code> derrière.</p>
<p>Certains serveurs ont un pare feu tatillon, et il faut rajouter dans la section <code>:RH-Firewall-1-INPUT - [0:0]</code> de iptable :</p>
<p><code>-A RH-Firewall-1-INPUT -p udp --dport 60000:61000 -j ACCEPT</code></p>
<p>D&#8217;autres ont des problèmes de locales:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">apt-get install --reinstall language-pack-fr
dpkg-reconfigure locales</pre></td></tr></table></div>

<p>Parfois y a aucun problème. C&#8217;est juste qu&#8217;on a pas un parc homogène, avec des bécanes vieilles de 1000 ans, alors forcément&#8230;</p>
<p>Mais Max a fait des devis, et si on passe au cloud avec les 2G/s de BP et les To de disque dur qu&#8217;on consomme, on multiplie les prix par 10 d&#8217;hébergement. Faire les trucs à la main, c&#8217;est chiant, mais c&#8217;est économe.</p>
<p>Pour mosh, pas de serveur à lancer, juste remplacer <code>ssh</code> par <code>mosh</code> dans la commande quand on se connecte. Des fois je lance avec <code>--predict=experimental</code> car je suis impatient et le retour de frappe est plus rapide, mais le cursor fait des mouvements bizarres, faut s&#8217;habituer.</p>
<p>Bon, on retourne faire des trucs plus productifs.</p>


feed_id: http://sametmax.com/?p=13066
title: Debugger Python à distance avec rpdb 7
uri: Debugger-Python-à-distance-avec-rpdb
url: http://sametmax.com/debugger-python-a-distance-avec-rpdb/
content:
<p>Vous aimez <a href="http://sametmax.com/debugger-en-python-les-bases-de-pdb/">pdb</a> parce que c&#8217;est cool. Et vous adorez <a href="https://pypi.python.org/pypi/pdbpp/">pdbpp</a> parce que c&#8217;est trop cool.</p>
<p>Mais parfois vous n&#8217;avez pas accès à une console sur votre process : il est derrière un nginx, ou même sur une machine distante.</p>
<p><a href="https://pypi.python.org/pypi/rpdb/">rpdb</a> vient résoudre ce problème en lançant un serveur telnet qui donne accès à votre debugger.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">pip <span style="color: #c20cb9; font-weight: bold;">install</span> rpdb</pre></td></tr></table></div>

<p>Puis :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> rpdb<span style="color: #66cc66;">;</span> rpdb.<span style="color: black;">set_trace</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Et après vous prenez votre client telnet favoris, et vous accédez à votre débugger :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">telnet 127.0.0.1 <span style="color: #000000;">4444</span></pre></td></tr></table></div>

<p>Bien entendu, si vous êtes à distance, remplacez 127.0.0.1 par l&#8217;ip de la machine. Le port est configurable également :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> rpdb
debugger <span style="color: #66cc66;">=</span> rpdb.<span style="color: black;">Rpdb</span><span style="color: black;">&#40;</span>port<span style="color: #66cc66;">=</span><span style="color: #ff4500;">12345</span><span style="color: black;">&#41;</span>
debugger.<span style="color: black;">set_trace</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Et derrière, ça lance <code>pdb</code>, donc <code>pdbpp</code> est lancé automatiquement si il est installé. Joie.</p>


feed_id: http://sametmax.com/?p=15699
title: Gérer plusieurs versions de Python avec “py” sous Windows 7
uri: Gérer-plusieurs-versions-de-Python-avec-py-sous-Windows
url: http://sametmax.com/gerer-plusieurs-versions-de-python-avec-py-sous-windows/
content:
<p>Il est courant de vouloir installer plusieurs versions de Python. Pour faire des tests, pour s&#8217;assurer que son code est portable, pour utiliser des libs qui marchent uniquement sur une des versions, etc.</p>
<p>Sous Linux, c&#8217;est facile : chaque interpretteur est préfixé. Par exemple, sous Ubuntu, si je veux utiliser Python 3.4, je l&#8217;installe :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> python3.4</pre></td></tr></table></div>

<p>Et si je lance <code>python</code>, ça me lance la 2.7 car c&#8217;est celle de base. Mais si je lance <code>python3.4</code>, ça me lance bien la 3.4. </p>
<p>Au final, on finit par utiliser des <a href="virtuels">environnements virtuels</a> qui isolent des versions de Python particulières. Mais ça ne retire pas l&#8217;envie de pouvoir choisir sa version de Python au niveau du système, ce qui reste difficile à faire sous Windows.</p>
<p>Or, depuis la version 3.3, l&#8217;installeur pour cet OS de Python installe la commande <a href="https://docs.python.org/3/using/windows.html#launcher">py</a>, qui permet de choisir quelle version de Python on lance.</p>
<h2>Dans un terminal</h2>
<p>Si dans une console vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py</pre></td></tr></table></div>

<p>Il lancera le shell de votre installation Python 2.x la plus récente.</p>
<p>Si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py script.py</pre></td></tr></table></div>

<p>Il exécutera le script avec votre installation Python 2.x la plus récente.</p>
<p>Mais vous pouvez passez un flag <code>-version</code> pour forcer une version de Python. Lancer le shell Python avec la 3.3 :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py -<span style="color: #000000;">3.3</span></pre></td></tr></table></div>

<p>Lancer un script avec la 3.4 :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py -<span style="color: #000000;">3.4</span> script.py</pre></td></tr></table></div>

<p>Cela suppose que vous avez la 3.3 et la 3.4, installés, évidement.</p>
<p>La syntaxe est surprenante. J&#8217;aurais pensé qu&#8217;ils mettraient un truc du genre <code>py -i 3.4</code> mais non, c&#8217;est direct <code>-numero</code>.</p>
<p>La commande <code>py</code> accepte aussi les paramètres qu&#8217;on passerait normalement à la commande <code>python</code>, et notament l&#8217;option <code>-m module</code>, qui permet de lancer un module en particulier. </p>
<p>C&#8217;est pratique pour lancer <code>ipython</code> ou <code>pip</code> avec une version particulière. Par exemple pour installer <a href="https://github.com/tavendo/AutobahnPython/">autobahn</a> uniquement pour la version 3.4 et donc utiliser <code>asyncio</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py -<span style="color: #000000;">3.4</span> <span style="color: #660033;">-m</span> pip <span style="color: #c20cb9; font-weight: bold;">install</span> autobahn</pre></td></tr></table></div>

<h2>Bang !</h2>
<p>La commande <code>py</code> reconnait également la ligne <em>shebang</em>, cette syntaxe unix qui dit quel interpretteur utiliser. Si vous mettez sur la première ligne de votre script :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! python3.4</span></pre></td></tr></table></div>

<p>Alors :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py script.py</pre></td></tr></table></div>

<p>Invoquera python 3.4.</p>
<p>La commande est capable de se débrouiller avec les chemins Unix, afin de garder la portabilité. Donc si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/env python2.7</span></pre></td></tr></table></div>

<p>Alors :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">py script.py</pre></td></tr></table></div>

<p>Va ignorer le debut de la ligne, et prendre l&#8217;installation locale de Python 2.7 pour lancer le script.</p>
<h2>On click</h2>
<p>Si vous installez la version Python 3.3 ou 3.4 en premier, les fichiers <code>.py</code> seront associés à la commande <code>py</code>. Donc si vous cliquez sur un script Python avec une ligne shebang, la bonne version sera lancée.</p>
<p>Mais si vous avez installé Python 2.x avant, il est possible que vos fichiers <code>.py</code> soient encore associés directement à la commande <code>python</code> ordinnaire.</p>
<p>Pour changer cela, faites un clic droit sur un fichier <code>.py</code>, modifiez le programme qui ouvre ce fichier et faites le pointer sur <code>"C:\Windows\py.exe"</code>.</p>


feed_id: http://sametmax.com/?p=11795
title: Hypnose & Domination 9
uri: Hypnose-Domination-2-Recently-updated
url: http://sametmax.com/hypnose-domination/
content:
<p style="text-align: center;"><em><small>Ceci est un post invité de <a href="http://sametmax.com/author/Bussiere/">Bussiere</a> posté sous licence <a href="http://creativecommons.org/licenses/by/3.0/">creative common 3.0 unported</a>.</small></em></p>
<p>Ce petit article a pour but d&#8217;expliquer selon moi ce qu&#8217;est l&#8217;hypnose et comment cela agit pour moi comme un exhausteur de gout pour la domination / sexe.</p>
<p>L&#8217;hypnose de mon point de vue est un hack du cerveau, il revient a faire tilter le cerveau de quelqu&#8217;un pour en prendre le contrôle.</p>
<p>Selon moi 95% des gens sont sensibles a l&#8217;hypnose et 15% de ses 95 % sont ultras sensibles.<br />
Les spectacles que vous verrez ne sont que sur les gens ultra sensibles, après la prise de drogue, le manque de sommeil et l&#8217;alcool peuvent rendre les gens ultra sensibles. De plus une personne qui perd ses repères devient plus sensible a l&#8217;hypnose j&#8217;ai déjà eu l&#8217;occasion de tester hypnose et <a href="http://www.urbex.me/">urbex</a> par exemple dans le cadre de la domination.</p>
<p>La domination et le <a href="http://fr.wikipedia.org/wiki/Extase_masochiste" title="subspace">sub space</a> pour moi se rapprochent énormément de l&#8217;hypnose, pour moi les deux étaient fait pour se Rencontrer.</p>
<p>De base la <a href="https://fetlife.com">domination</a> rend quelqu&#8217;un de sensible ultra sensible, et quelqu&#8217;un ayant jouis et du coup abaissant toute ses défense devient ultra sensible a l&#8217;hypnose de même que quelqu&#8217;un en subspace.</p>
<p><img src="media/c1cd0d39.5027310004e8cf9557396b4ba55c10284a7dec720.jpg" data-original-source="http://img11.hostingpics.net/pics/5027310004e8cf9557396b4ba55c10284a7dec720.jpg" alt="Exemple" /></p>
<p>J&#8217;utilise l&#8217;hypnose en domination de plusieurs manières :</p>
<p>Soit pour laisser des mots de commande exemples :</p>
<p>Miaouss pour que la soumise ne puisse que miauler et ne plus parler.<br />
Persian pour qu&#8217;elle puisse reparler de nouveau<br />
Spectre pour qu&#8217;elle se mette a genoux et ne puisse plus bouger.<br />
Piroli pour qu&#8217;elle se fasse plaisir seule.<br />
Rondoudou pour qu&#8217;elle s&#8217;endorme et parte.<br />
Dracofeu pour la montée de chaleur.</p>
<p>Le plus amusant étant de pouvoir jouer avec des mots de commande en public&#8230;</p>
<p>Soit par association :</p>
<p>J&#8217;associe les cordes au plaisir </p>
<p><img src="media/fc95913d.4552350004ee5d0415a5bfba9fc1051c11d1c6720.jpg" data-original-source="http://img4.hostingpics.net/pics/4552350004ee5d0415a5bfba9fc1051c11d1c6720.jpg" alt="Voila ce que je fais et un mec pour changer un peu" /></p>
<p>et quand j&#8217;attache quelqu&#8217;un, cette personne ressent des montées de chaleur plus les cordes la touche. Chose que je fais souvent en performance.</p>
<p>J&#8217;ai remarqué que les cordes augmentaient les effets de l hypnose au point ou j&#8217;ai des amies qui me demande de les attacher habillées et de les hypnotiser pour les détendre après.</p>
<p>Une chose amusante est aussi de lier un foulard au plaisir et de passer le foulard sur le corps.</p>
<p>Mais sans aller jusqu’à l&#8217;hypnose &#8220;dure&#8221; le conditionnement fait partie de l&#8221;hypnose et tout le monde peut le faire. Prenez du velours, si dans les préliminaire quand votre partenaire éprouve du plaisir vous jouez avec un morceau de velours régulièrement, ce morceau de velours sera associé au plaisir. Donc il y aura un effet d&#8217;association qui décuplera le reste, et parfois selon votre partenaire juste sortir ce morceau de tissus suffira a le / la faire rougir.</p>
<p>Soit pour augmenter la sensibilité au reste :<br />
Il suffit par hypnose de conditionner la personne et de lui augmenter tout les sens pour qu&#8217;elle ressente encore plus de choses.</p>
<p>Apres l&#8217;hypnose fait peur j&#8217;ai des personnes qui acceptent de me laisser leur corps, je peux les attacher nues mais pas toucher a leur esprit. C&#8217;est leur choix et je le respecte mais j&#8217;ai du mal a comprendre dans la mesure ou le corps pour moi est une porte sur l&#8217;esprit.</p>
<p>J&#8217;aimerai savoir si d&#8217;autres personnes pratiquent aussi l&#8217;hypnose avec la domination ici.</p>
<p>Et en tant que dominateur j’apprécie particulièrement le contrôle sur l&#8217;esprit qui pour moi est largement au dessus du corps surtout chez les femmes. Les femmes étant largement plus mental que les hommes, arriver a jouer avec leur esprit est une satisfaction largement plus gratifiante que juste jouer avec les corps.</p>
<p>Sérieusement si vous arrivez a tenir une femme par le mental vous l&#8217;emmenez ou vous voulez &#8230;<br />
Tout ce qui est préliminaires , jeux , situations , rôles contribue a conditionner une femme et a lui donner plus de plaisir. Sans aller jusqu’à l’hypnose je recommande d’être joueur.</p>
<p>L&#8217;hypnose est un outil très intéressant pour tout ce qui touche a la domination si on le rajoute au reste, il en multiplie les effets et le reste décuple les effets de l&#8217;hypnose.</p>
<p>Quand vous forcez quelqu&#8217;un a se mettre a genoux devant vous , ou qu&#8217;il est vulnérable face a vous l&#8217;hypnose marchera mieux. Quand vous faites oublier son nom a quelqu&#8217;un en &#8220;jouant&#8221; avec lui il devient plus sensible a l&#8217;hypnose.</p>
<p>Bon par contre il y a des questions d’éthiques , personnellement j&#8217;ai l’éthique du bdsm qui consiste en un safe word, d’être sur du consentement de la personne sans aucun biais (hypnose, alcool , drogue , fatigue) et souvent de définir un contrat avec la personne sur les choses permises. Et en cas d&#8217;absence de contrat je m’abstiens de toute choses plus poussées et j&#8217;y vais par pallier.</p>
<p>Ma plus belle réussite reste d&#8217;arriver a faire se mettre a genoux et immobiliser une soumise puis la faire jouir en claquant des doigts sans la toucher, tout avec la voix.</p>
<p>Dans un autre domaine j&#8217;ai fait un petit jeu open source basé sur l&#8217;hypnose :<br />
<a href="http://ragemag.fr/oculus-rift-hypnose-virtuelle-ragemag-mystifier-jeu-video-45716/" title="http://ragemag.fr/oculus-rift-hypnose-virtuelle-ragemag-mystifier-jeu-video-45716/">http://ragemag.fr/oculus-rift-hypnose-virtuelle-ragemag-mystifier-jeu-video-45716/</a></p>
<p>Et un type que je recommande derren brown :<br />
<a href="https://www.youtube.com/user/OfficialDerren" title="https://www.youtube.com/user/OfficialDerren">https://www.youtube.com/user/OfficialDerren</a></p>
<p>Et pour finir une petite chanson :<br />
<iframe width="420" height="315" src="//www.youtube.com/embed/ElxbOr4b-vs" frameborder="0" allowfullscreen></iframe></p>


feed_id: http://sametmax.com/?p=15712
title: Qu’est-ce que le duck typing et à quoi ça sert ? 5
uri: Qu-est-ce-que-le-duck-typing-et-à-quoi-ça-sert-3-Recently-upd
url: http://sametmax.com/quest-ce-que-le-duck-typing-et-a-quoi-ca-sert/
content:
<p>Le duck typing, qu&#8217;on pourrait traduire par &#8220;typage canard&#8221; mais on ne le fera pas parce que c&#8217;est très moche, est une manière de créer des <a href="http://sametmax.com/quest-ce-quune-api/">APIs</a> basée sur la philosophie que l&#8217;aspect pratique est plus important que la pureté du code.</p>
<p>L&#8217;idée est de créer des signatures de <a href="http://sametmax.com/les-trucmuchables-en-python/">callable</a> qui acceptent des paramètres en fonction de leur comportement, pas leur type :</p>
<blockquote><p>Si ça marche comme un canard et que ça fait le bruit d&#8217;un canard, alors ça ressemble assez à un canard pour le traiter comme un canard</p></blockquote>
<p>Imaginez que vous ayez un objet avec un interface ICanard:</p>
<pre>
class ICanar:
    def coin():
        pass
</pre>
<p>Une fonction qui est programmée selon le duck typing acceptera comme argument un objet qui possède la méthode <code>coin</code>, peut importe si il implémente cette interface ou non.</p>
<p>En gros, si un paramètre possède une interface suffisante pour nous, ou peut être casté en un objet avec une interface suffisante pour nous, on l&#8217;accepte. Cela rend un callable plus générique.</p>
<p>Ok, trève de bavardage, qu&#8217;est-ce que ça implique, dans la vraie vie vivante ?</p>
<p>Si je fais une fonction qui retourne le premier élément d&#8217;une liste ou un élément par défaut :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> getfirst<span style="color: black;">&#40;</span>lst<span style="color: #66cc66;">,</span> default<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> lst<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> default</pre></td></tr></table></div>

<p>Pratique, et ça marche sur d&#8217;autres itérables :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> getfirst<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> getfirst<span style="color: black;">&#40;</span><span style="color: #483d8b;">'abcde'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'a'</span></pre></td></tr></table></div>

<p>On a une forme de duck typing : si on peut récupérer le premier élément, alors ça suffit pour nous. Peut importe qu&#8217;il s&#8217;agit d&#8217;une liste ou d&#8217;un tuple.</p>
<p>On peut néanmoins améliorer la généricité de cette fonction:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> getfirst<span style="color: black;">&#40;</span>iterable<span style="color: #66cc66;">,</span> default<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        <span style="color: #ff7700;font-weight:bold;">return</span> x
    <span style="color: #ff7700;font-weight:bold;">return</span> default</pre></td></tr></table></div>

<p>Ici, le comportement recherché est qu&#8217;on puisse faire une une boucle <code>for</code> dessus, pas qu&#8217;on puisse récupérer un élément par son index.</p>
<p>Cela rend la fonction encore plus flexible, ainsi elle marche sur les générateurs, les flux, les fichiers:</p>
<pre lang"python>>>> getfirst(open('/etc/fstab'))
'# /etc/fstab: static file system information.\n'</pre>
<p>Un autre exemple ? La fonction Python <code>sum</code> par exemple, accepte tout types de nombres :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># integers</span>
<span style="color: #ff4500;">6</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1.3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2.4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3.5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># floats</span>
<span style="color: #ff4500;">7.2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>1j<span style="color: #66cc66;">,</span> 2j<span style="color: #66cc66;">,</span> 3j<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># complexes</span>
6j</pre></td></tr></table></div>

<p>Sympas, mais l&#8217;addition en Python supporte bien plus que les nombres :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> + <span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> + <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #483d8b;">&quot;a&quot;</span> + <span style="color: #483d8b;">&quot;b&quot;</span>
<span style="color: #483d8b;">'ab'</span></pre></td></tr></table></div>

<p>Mais <code>sum</code> ne les accepte pas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;a&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;b&quot;</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-24-1e5baeda1183&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;a&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;b&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> can<span style="color: #483d8b;">'t sum strings [use '</span><span style="color: #483d8b;">'.join(seq) instead]</span></pre></td></tr></table></div>

<p>Il est possible de faire un <code>sum</code> plus générique :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> sumum<span style="color: black;">&#40;</span>*iterable<span style="color: #66cc66;">,</span> start<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> default<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># On donne à l'utilisateur la possibilité</span>
    <span style="color: #808080; font-style: italic;"># de passer un premier élément</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> start <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #808080; font-style: italic;"># on récupère le premier élément</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            start<span style="color: #66cc66;">,</span> *iterable <span style="color: #66cc66;">=</span> iterable
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
            <span style="color: #808080; font-style: italic;"># Il n'y a aucun élément dans l'itérable</span>
            <span style="color: #808080; font-style: italic;"># donc on retourne la valeur par default</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> default
    <span style="color: #808080; font-style: italic;"># on additionne</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        start +<span style="color: #66cc66;">=</span> x
    <span style="color: #ff7700;font-weight:bold;">return</span> start</pre></td></tr></table></div>

<p>Le duck typing, à son maximum :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> sumum<span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'b'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'c'</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'abc'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> sumum<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span></pre></td></tr></table></div>

<p>Le duck typing implique aussi une prise de décision. Qu&#8217;est-ce qui serait le plus pratique ? De pouvoir additionner tous les types additionnables ? Ou de pouvoir additionner n&#8217;importe quoi qui ressemble à un nombre ?</p>
<p>Imaginons que la plupart de nos libs, plutôt que de fournir la possibilité d&#8217;additionner, propose la possibilité de caster vers un <code>float</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Temperature:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> value<span style="color: #66cc66;">,</span> unit<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'C'</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">value</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">unit</span> <span style="color: #66cc66;">=</span> unit
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__float__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">unit</span> <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'C'</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">value</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">unit</span> <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'K'</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">value</span> - <span style="color: #ff4500;">273.15</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">unit</span> <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'F'</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">value</span> - <span style="color: #ff4500;">32</span><span style="color: black;">&#41;</span> * <span style="color: #ff4500;">5</span>/<span style="color: #ff4500;">9</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__repr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'%s %s'</span> % <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">value</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">unit</span> <span style="color: #66cc66;">!=</span> <span style="color: #483d8b;">'K'</span><span style="color: black;">&#41;</span>*<span style="color: #483d8b;">'°'</span>+<span style="color: #008000;">self</span>.<span style="color: black;">unit</span><span style="color: black;">&#41;</span>
&nbsp;
t1 <span style="color: #66cc66;">=</span> Temperature<span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
t2 <span style="color: #66cc66;">=</span> Temperature<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'K'</span><span style="color: black;">&#41;</span>
t3 <span style="color: #66cc66;">=</span> Temperature<span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'F'</span><span style="color: black;">&#41;</span>
t1<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">,</span> t3
<span style="color: #808080; font-style: italic;">## (5.0 °C, 3.0 K, 30.0 °F)</span></pre></td></tr></table></div>

<p>Dans ce cas notre fonction pourrait convertir tous les éléments d&#8217;un itérable avant addition :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> sumcast<span style="color: black;">&#40;</span>*iterable<span style="color: #66cc66;">,</span> start<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> default<span style="color: #66cc66;">=</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># On donne à l'utilisateur la possibilité</span>
    <span style="color: #808080; font-style: italic;"># de passer un premier élément</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> start <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #808080; font-style: italic;"># on récupère le premier élément</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            start<span style="color: #66cc66;">,</span> *iterable <span style="color: #66cc66;">=</span> iterable
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
            <span style="color: #808080; font-style: italic;"># Il n'y a aucun élément dans l'itérable</span>
            <span style="color: #808080; font-style: italic;"># donc on retourne la valeur par default</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> default
    <span style="color: #808080; font-style: italic;"># on additionne en convertissant tout en float</span>
    start <span style="color: #66cc66;">=</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>start<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterable:
        start +<span style="color: #66cc66;">=</span> <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> start
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> sumcast<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;3&quot;</span><span style="color: #66cc66;">,</span> t1<span style="color: #66cc66;">,</span> t2<span style="color: #66cc66;">,</span> t3<span style="color: black;">&#41;</span>
-<span style="color: #ff4500;">262.26111111111106</span></pre></td></tr></table></div>

<p>Dans tous les cas, on se fiche complètement que nos objets soient d&#8217;un type précis ou qu&#8217;ils implémentent une interface précise à partir du moment où leur API est suffisamment proche du ce type ou de l&#8217;interface dont on a besoin.  </p>
<p>Le duck typing a beau être une pratique vouée à simplifier la vie au prix du formalisme, il ne dispense pas de documenter votre code à propos de cette subtilité afin que l&#8217;utilisateur final n&#8217;ait pas de mauvaise surprise.</p>
<p>Il convient de ne pas abuser du duck typing, qui est là pour rendre service uniquement. Si vous ajoutez des cas farfelus dans votre code pour supporter des situations rares, vous le rendez plus compliqué et moins robuste. Visez la généricité pour les situations les plus courantes, pas toutes les situations possibles.</p>
<p>Et souvenez-vous que plus on est dynamique sur les types, plus on perd en performance. Il faut savoir quelle part de compromis on est prêt à faire.</p>


feed_id: http://sametmax.com/?p=15704
title: Rendez votre package exécutable avec __main__.py 5
uri: Rendez-votre-package-exécutable-avec-__main__-py-Recently-updated
url: http://sametmax.com/rendez-votre-module-executable-avec-__main__-py/
content:
<p>Tout le monde connait le fichier <a href="http://sametmax.com/vous-pouvez-mettre-du-code-dans-__init__-py/">__init__.py</a>, mais <code>__main__.py</code> est moins connu.</p>
<p>Il permet de lancer du code si on tente d&#8217;exécuter un package (c&#8217;est à dire un dossier qui contient un fichier <code>__init__.py</code>):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">tree</span> monpackage<span style="color: #000000; font-weight: bold;">/</span>
monpackakge<span style="color: #000000; font-weight: bold;">/</span>
├── __init__.py
└── __main__.py
&nbsp;
<span style="color: #000000;">0</span> directories, <span style="color: #000000;">2</span> files
$ <span style="color: #c20cb9; font-weight: bold;">cat</span> monpackage<span style="color: #000000; font-weight: bold;">/</span>__main__.py
print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'Hello :)'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ python monpackage<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #666666; font-style: italic;"># ceci est un dossier </span>
Hello :<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>Le <code>__main__.py</code>  est aussi exécuté quand on fait <code>python -m monpackage</code>. </p>
<p>Notez que son exécution suppose l&#8217;import préalable du package, et que donc <code>__init__.py</code> sera toujours exécuté avant <code>__main__.py</code>. En revanche, faire juste <code>import monpackage</code> ne déclenche pas l&#8217;exécution de <code>__main__.py</code>.</p>
<p>Si vous zippez votre package et appelez la commande <code>python</code>, c&#8217;est aussi ce fichier qui sera exécuté. Pratique donc, pour faire un exécutable portable à peu de frais, tout en gardant la lib importable.</p>


feed_id: http://sametmax.com/?p=15727
title: Embeder Python dans du C ou C++ 6
uri: Embeder-Python-dans-du-C-ou-C-Recently-updated
url: http://sametmax.com/embeder-python-dans-du-c-ou-c/
content:
<p>L&#8217;implémentation de référence de Python est écrite en C, et son API est exposée et bien <a href="https://docs.python.org/2/c-api/">documentée</a>. Il est donc possible de créer des objets Python, charger un module Python ou exécuter une fonction Python depuis un code C/C++ et compiler tout ça.</p>
<p>Mettons que j&#8217;ai dans un fichier <code>biblio.py</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> yolo<span style="color: black;">&#40;</span>arg<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> arg.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' !!'</span></pre></td></tr></table></div>

<p>Je peux écrire un fichier <code>prog.c</code> qui l&#8217;utilise :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;Python.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// PyObject est un wrapper Python autour des objets qu'on</span>
    <span style="color: #666666; font-style: italic;">// va échanger enter le C et Python.</span>
    PyObject <span style="color: #339933;">*</span>retour<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>module<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>fonction<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>arguments<span style="color: #339933;">;</span>
    <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>resultat<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Initialisation de l'interpréteur. A cause du GIL, on ne peut</span>
    <span style="color: #666666; font-style: italic;">// avoir qu'une instance de celui-ci à la fois.</span>
    Py_Initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   
&nbsp;
    <span style="color: #666666; font-style: italic;">// Import du script. </span>
    PySys_SetPath<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Le dossier en cours n'est pas dans le PYTHON PATH</span>
    module <span style="color: #339933;">=</span> PyImport_ImportModule<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;biblio&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Récupération de la fonction</span>
    fonction <span style="color: #339933;">=</span> PyObject_GetAttrString<span style="color: #009900;">&#40;</span>module<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;yolo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Création d'un PyObject de type string. Py_BuildValue peut créer</span>
    <span style="color: #666666; font-style: italic;">// tous les types de base Python. Voir :</span>
    <span style="color: #666666; font-style: italic;">// https://docs.python.org/2/c-api/arg.html#c.Py_BuildValue</span>
    arguments <span style="color: #339933;">=</span> Py_BuildValue<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;(s)&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Leroy Jenkins&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
    <span style="color: #666666; font-style: italic;">// Appel de la fonction.</span>
    retour <span style="color: #339933;">=</span> PyEval_CallObject<span style="color: #009900;">&#40;</span>fonction<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Conversion du PyObject obtenu en string C</span>
    PyArg_Parse<span style="color: #009900;">&#40;</span>retour<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;s&quot;</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>resultat<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Resultat: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> resultat<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// On ferme cet interpréteur.</span>
    Py_Finalize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Là je mets du C, mais la seule vraie différence avec du C++, c&#8217;est qu&#8217;on aurait <code>cout</code> au lieu de <code>printf</code>.</p>
<p>Pour compiler tout ça, il faut les headers Python et un compilateur. Sous Ubuntu, c&#8217;est un simple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> python-dev <span style="color: #c20cb9; font-weight: bold;">gcc</span></pre></td></tr></table></div>

<p>Et on a tout nos <code>.h</code> dans /usr/include/python2.7. On gccise :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">gcc</span> -I<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>include<span style="color: #000000; font-weight: bold;">/</span>python2.7 prog.c -lpython2.7 <span style="color: #660033;">-o</span> prog <span style="color: #660033;">-Wall</span>  <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> .<span style="color: #000000; font-weight: bold;">/</span>prog</pre></td></tr></table></div>

<p>Même pas un warning, c&#8217;est beau.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>prog
Resultat: LEROY JENKINS <span style="color: #000000; font-weight: bold;">!!</span></pre></td></tr></table></div>

<p>C&#8217;est un exemple simple, mais comme vous le savez je suis une grosse burne en C, donc je ne pourrai pas porter l&#8217;expérience plus loin.</p>
<p>Je ne le recommande pas pour rendre votre programme scriptable en Python. Il <a href="http://twistedmatrix.com/users/glyph/rant/extendit.html">vaut mieux</a> permettre à Python d&#8217;appeler votre code C dans ce cas. Des outils comme <a href="https://cffi.readthedocs.org/en/release-0.8/">cffi</a> rendent cela beaucoup plus facile et rentable que tout faire tout le taff à la main. D&#8217;ailleurs si quelqu&#8217;un est chaud pour faire un tuto sur cffi&#8230;</p>
<p>Non, c&#8217;est plus dans le cas où vous avez un programme C, un programme Python, et votre programme C veut utiliser le programme Python sans avoir à tout réécrire. Ou pour le cas où vous avez décidé d&#8217;écrire une grosse partie de votre programme en Python pour profiter de sa productivité, mais que vous ne pouvez pas installer Python sur la machine sur laquelle vous aller installer le programme. Bon, y a <a href="https://github.com/pyinstaller/pyinstaller/wiki">PyInstaller</a> et <a href="http://nuitka.net/">Nuitka</a> pour ça également hein, donc tentez avant de tout embeder comme un bourrin.</p>
<p>Ça reste intéressant de voir les entrailles de CPython et à quel point il joue bien avec les langages bas niveaux.</p>


feed_id: http://sametmax.com/?p=15736
title: Je me te tâte à arrêter le tuto Angular 34
uri: Je-me-te-tâte-à-arrêter-le-tuto-Angular-9-Recently-updated
url: http://sametmax.com/je-me-te-tate-a-arreter-le-tuto-angular/
content:
<p>Malgré les <a href="https://medium.com/este-js-framework/what-i-would-recommend-instead-of-angular-js-62b057d8a9e">critiques</a>, j&#8217;aime beaucoup AngularJS. Mais à <a href="http://www.i-programmer.info/news/167-javascript/7932-angularjs-20-is-radically-different-.html">l&#8217;annonce</a> de la version 2 d&#8217;Angular complètement incompatible avec la version 1, seulement quelques années après sa sortie, des questions <a href="http://www.quirksmode.org/blog/archives/2015/01/the_problem_wit.html">se sont posées</a> sur l&#8217;avenir du framework.</p>
<p>J&#8217;utilise AngularJS pour certains de mes projets, je suis payé pour former sur AngularJS et j&#8217;ai commencé à écrire <a href="http://sametmax.com/angularjs-pour-les-utilisateurs-de-jquery-partie-1/">un guide</a> sur le sujet.</p>
<p>Mais je me demande franchement si ça vaut le coup de s&#8217;investir plus.</p>
<p>Je vais continuer à l&#8217;utiliser pour mes projets actuels, tout en regardant du côté de la concurrence <a href="http://facebook.github.io/flux/">ici</a> et <a href="http://facebook.github.io/react/">là</a>.</p>
<p>Si j&#8217;écris l&#8217;article, ce n&#8217;est pas pour vous alarmer. Ni même pour vous dire &#8220;arrêtez d&#8217;utiliser Angular&#8221;. Je pense que la V1 va être maintenue par la communauté pendant des années.</p>
<p>Non, je me demande simplement si ça vaut le coup que je me casse le cul à finir le guide.</p>
<p>J&#8217;ai du travail à la pelle, le<a href="http://sametmax.com/un-gros-guide-bien-gras-sur-les-tests-unitaires-en-python-partie-1/"> guide sur les tests en Python</a>, <a href="https://github.com/sametmax/Django--an-app-at-a-time/tree/fran%C3%A7ais">Django une app à la fois</a>, 0bin à porter en Python 3&#8230;</p>
<p>Bref, est-ce que vous êtes toujours aussi intéressés par ce guide ?</p>


feed_id: http://sametmax.com/?p=15749
title: Comment utiliser IndexError ? 10
uri: Comment-utiliser-IndexError-3-Recently-updated
url: http://sametmax.com/comment-utiliser-indexerror/
content:
<p>Après un peu de rodage, <a href="http://indexerror.net">IndexError</a> est sur les rails : design amélioré, meilleur perfs, workflow plus clair, etc.</p>
<p>Néanmoins on a été très surpris avec Max : la plupart des utilisateurs n&#8217;ont aucune idée de comment on s&#8217;en sert.</p>
<p>Pourtant c&#8217;est un clone de <a href="http://stackoverflow.com">Stackoverflow</a>, un site tellement célèbre qu&#8217;il est dans la première page des résultats de Google pour toutes les recherches techniques.</p>
<p>Pourtant c&#8217;est un simple site de question/réponse.</p>
<p>Pourtant on passe régulièrement dans les commentaires pour expliquer le principe.</p>
<p>Malgré ça, les gens se mélangent les pinceaux, ou ont peur de mal faire, ou ne savent trop par où commencer. </p>
<p>Cela prouve une fois de plus ce que j&#8217;<a href="http://sametmax.com/bien-expliquer-quelque-chose-les-regles-de-base/">arrête</a> pas de <a hre"http://sametmax.com/il-ne-faut-pas-prendre-des-gens-pour-des-cons-mais-ne-jamais-oublier-quils-en-sont/>répéter</a> : l&#8217;évidence n&#8217;existe pas.</p>
<h2>A quoi sert IndexError ?</h2>
<p>A obtenir une réponse à sa question sur Python et son écosystème. C&#8217;est tout.</p>
<p>Pas à lancer un débat. Pas à discuter ou socialiser.</p>
<p>Le but est très simple : rendre service à celui qui pose la question maintenant mais aussi <strong>à ceux qui se la poseront dans le future.</strong></p>
<p>Sur le site, ça se traduit par avoir pour chaque question une page avec :</p>
<pre>[Titre de la question en gros]

| Détails de la question pour
| mieux comprendre le contexte

[Solution la plus probable]

[Solution un peu moins probable]

[Solution encore un peu moins probable]

[Solution encore un peu moins probable]

[Solution encore un peu moins probable]

Etc.</pre>
<h2>Comment on obtient ce résultat ?</h2>
<p>D&#8217;abord en virant tout l&#8217;enrobage. Pas de &#8220;bonjour&#8221;, &#8220;merci&#8221;, &#8220;je suis débutant&#8221;, etc. On pose la question, on donne une réponse.</p>
<p>Ensuite, en ne se souciant pas d&#8217;avoir tort. </p>
<p>Si vous pensez qu&#8217;une question est stupide, vous pouvez la poser.</p>
<p>Si vous n&#8217;êtes pas certain que votre réponse est la bonne, vous pouvez la donner.</p>
<p>Si vous pensez que la réponse est sur Google, vous pouvez la poser.</p>
<p>Pour citer un commentaire célèbre sur Stackoverflow : </p>
<blockquote><p>Chercher sur ce site plutôt que Google, c&#8217;est comme fait un accès hashmap plutôt que de parcourir une linked list.</p></blockquote>
<p>C&#8217;est le but : avoir toutes les questions possibles, et les réponses possibles à cette question.</p>
<p>En clair, si quelqu&#8217;un vous dis que votre question est conne ou vous dis de chercher sur Google dans un commentaire sur IndexError, vous pouvez l&#8217;envoyer se faire foutre.</p>
<p>IndexError est là pour faire gagner du temps. Être efficace. Résoudre des problèmes.</p>
<p>Ça ne vous dispense pas de rechercher si la question n&#8217;a pas déjà été posée sur le site avant de la poser, bien entendu.</p>
<h2>Commentaire VS Réponse</h2>
<p>Il y a beaucoup de confusion sur quand commenter, et quand répondre.</p>
<p><strong>Si vous êtes l&#8217;auteur de la question, vous voudrez presque toujours commenter.</strong> Il est très rare de répondre à sa propre question. C&#8217;est possible, et même encouragé si vous avez trouvé la réponse, mais c&#8217;est rare.</p>
<p>Si vous n&#8217;êtes pas l&#8217;auteur de la question :</p>
<ul>
<li>Toute demande d&#8217;informations supplémentaires ou remarque va en commentaire.</li>
<li>Toute solution possible va dans une réponse.</li>
</ul>
<p>Ex :</p>
<p><em>Il va falloir que tu nous poste ton fichier de config.</em> => commentaire.</p>
<p><em>Remplace True par False pour voir ce que ça fait</em> => réponse.</p>
<p>Et c&#8217;est la l&#8217;astuce : <strong>vous n&#8217;avez pas besoin d&#8217;être certain que votre réponse est la bonne</strong> pour la poster.</p>
<p>Les votes sont faits pour ça.</p>
<p>Postez toutes les solutions qui vous viennent en tête comme réponse, pas comme commentaire.</p>
<p>Si ce n&#8217;est pas la solution appropriée, la bonne sera votée,  montera dans le classement et passera devant la votre donc ce n&#8217;est pas grave. Mais plus tard, un mec peut passer, chercher la réponse à la question, et voir que VOTRE réponse est SA solution.</p>
<h2>Votez</h2>
<p>Pour que ça marche, il faut donc voter. Si une question est pertinente, votez la. Si une réponse est pertinente, votez la. Même si vous n&#8217;êtes pas l&#8217;auteur de la question. Voter fait parti intégrante de la participation au site.</p>
<p>La plupart du temps, on upvote, les quelques raisons possibles de downvote :</p>
<ul>
<li>La réponse est hors sujet, incompréhensible ou un spam.</li>
<li>La réponse est rédigée par un connard agressif.</li>
<li>Vous pensez que la réponse apporte plus de problèmes qu&#8217;elle n&#8217;en résout. Dans ce cas, signalez le downvote et justifiez le en commentaire.</li>
</ul>
<p><strong>Tout vote est annulable, donc n&#8217;ayez pas peur.</strong></p>
<p>De même, si une réponse est la solution à votre question, cliquez sur le symbole  	&#10003; à gauche de la réponse pour l&#8217;accepter. Ceci la propulse tout en haut de la liste des réponses, et change son style pour qu&#8217;elle soit plus visible. </p>
<p>En prime, toutes ces actions donnent des points, et les points sont importants, ce ne sont pas de simples gommettes pour gonfler l&#8217;égo des enfants de maternelle.</p>
<h2>Les points</h2>
<p>Ils servent à 2 choses.</p>
<p>D&#8217;une part, à permettre d&#8217;identifier les participants du site selon leur réputation. Si un réponse ou un commentaire est fait par quelqu&#8217;un de haute réputation, on peut se dire qu&#8217;on va y prêter plus d&#8217;attention qu&#8217;aux autres. C&#8217;est un gain de temps.</p>
<p>Mais surtout, les points sont attachées à des permissions.</p>
<p>En effet, sur IndexError, une autre personne peut éditer VOS questions et commentaires, comme sur un wiki. Le droit de faire cela ou non est lié au nombre de points qu&#8217;il a.</p>
<p>Voter donne des points. Poser des questions donne des points. Donner des réponses donne des points. Accepter des réponses donne des points.</p>


feed_id: http://sametmax.com/?p=15766
title: Le don du mois : Mozilla 9
uri: Le-don-du-mois-Mozilla-Recently-updated
url: http://sametmax.com/le-don-du-mois-mozilla/
content:
<p>Régulièrement, je donne à des organismes. Je ne pense pas qu&#8217;il y ait un combat plus important que d&#8217;autres. Si une personne veut supporter les yorkshires dépressifs anorexiques, une autre les goths hémophiles sidaïques et une dernière les ti nenfants qui meurent de la faim mortelle dans le monde mondial, très bien.</p>
<p>Personnellement, j&#8217;ai tendance à donner à des entités qui ont produit un travail concret dont j&#8217;ai pu profiter des fruits dans ma vie. Je suis un égoïste. Typiquement : la quadrature du Net, VLC, Ubuntu, Libre Office, Debian, la Python et la Free Software Fondation, Wikipedia, etc.</p>
<p>Mais comment motiver les gens à donner ? </p>
<p>Ça c&#8217;est plus compliqué. Tous les bloggers le savent, nos liens en bas qui demandent la charité rapportent peau de balle. En deux ans, on a récolté 200 euros avec flatr et 0.x bitcoins.</p>
<p>Du coup je me suis dit que peut être en donnant l&#8217;exemple on allait créer des vocations. Voilà donc l&#8217;idée : à chaque fois que je vais donner des sous, je vais écrire un article pour dire à qui, combien, et pourquoi.</p>
<p>Le but est multiple :</p>
<ul>
<li>Faire une piqûre de rappel régulière. Moi-même, j&#8217;oublie de donner, et je n&#8217;ai pas l&#8217;intention de faire des dons mensuels automatiques.</li>
<li>Faire déculpabiliser les gens sur la somme ou la cible. Il n&#8217;y a pas de petite action. Si vous donnez 1 euro, une seule fois à <a href="http://www.fdn.fr/">FDN</a>, et plus jamais, personne va venir vous engueuler. </li>
<li>Faire parler un peu de l&#8217;organisme qui en bénéficie. Peut être que les lecteurs donneront un peu à eux également.</li>
</ul>
<h2>Et le gagnant du jour est Momo</h2>
<p>Mozilla, la boîte qui a fait Firefox, est vraiment, mais alors vraiment formidable.</p>
<p>Ce sont les premiers à avoir fournit un logiciel libre de qualité pour surfer le Web. Souvenez-vous : d&#8217;abord il s&#8217;appelait Pheonix, puis Firebird, avant de devenir Firefox, mais il est là depuis 13 ans ! S&#8217;inspirant du très beau Opera, il a proposé des fonctionnalités qui paraissent évidentes aujourd&#8217;hui comme les onglets, le blocage de pop up ou la complétion des champs de formulaires. Et surtout, <strong> il a popularisé le principe des extensions.</strong></p>
<p>Firefox, et donc Mozilla, est la raison pour laquelle vous pouvez profiter de pages sans pub grâce à <a href="http://en.wikipedia.org/wiki/Adblock_Plus">Adblock</a> aujourd&#8217;hui.</p>
<p>Firefox est la seule raison pour laquelle on s&#8217;est pas bouffé de l&#8217;IE pendant toutes ses années, Firefox est celui qui a montré la voie à l&#8217;équipe de Google pour qu&#8217;ils lancent Chrome, et la bataille sur les perfs d&#8217;affichage et d&#8217;exécution JS dont on bénéficie aujourd&#8217;hui.</p>
<p>Mais Mozilla, ce n&#8217;est pas que Firefox.</p>
<p>C&#8217;est une association à but non lucratif qui passe son temps à défendre le Web ouvert. En se battant sur les <a href="https://wiki.mozilla.org/Standards">standards</a>, en <a href="https://developer.mozilla.org/fr/">documentant</a> et en continuant de prendre des risques dans une industrie de plus en plus conservatrice.</p>
<p>En effet, malgré des revenus très inférieurs à la plupart des acteurs concurrents, Mozilla s&#8217;est lancé dans :</p>
<ul>
<li>La création d&#8217;un <a href="https://www.mozilla.org/en-US/firefox/os/">OS pour téléphone</a> entièrement libre et basés sur les technologies du Web. Sans Bidule store qui enferme les utilisateurs et développeur.</li>
<li>L&#8217;ajout de la VOIP (pensez skype) <a href="https://support.mozilla.org/en-US/kb/firefox-hello-video-and-voice-conversations-online">directement dans Firefox</a>, sans aucune inscription.</li>
<li>L&#8217;ajout d&#8217;une fonctionnalité de <a href="https://activations.cdn.mozilla.net/fr/">partage générique des liens.</a></li>
<li><a href="http://popcornjs.org/">Popcorn.js</a>, une lib pour augmenter l&#8217;interaction avec les videos HTML5.</li>
<li><a href="https://mozillalabs.com/en-US/pdfjs/">PFD.js</a>, une lib pour faire un rendu d&#8217;un PDF en pure JS.</li>
<li><a href="https://mozillalabs.com/en-US/togetherjs/">TogetherJS</a>, une lib pour faciliter le travail collaboratif sur une page.</li>
<li><a href="http://circus.readthedocs.org/en/0.11.1/">Circus</a>, un gestionnaire de processus clusterisable.</li>
</ul>
<p>Leurs projets libres sont <a href="https://github.com/mozilla">nombreux</a>, et il y en a plein en Python.</p>
<p>Mozilla est aussi le seul acteur à ne pas censurer son store pour répondre à ses besoins mercantiles. </p>
<p>Et les gars sont très approchables. Vous pouvez littéralement envoyer un tweet à Tarek Ziadé ou Tristan Nitot et avoir une réponse.</p>
<h2>Le don</h2>
<p>Il se trouve que Mozilla accepte les bitcoins sur <a href="https://sendto.mozilla.org/page/contribute/givenow-seq?source=base_url#page-1">sa page de don</a> \o/. Ils utilisent <a href="https://www.coinbase.com">Coinbase</a> comme plateforme, ce qui leur permet de hooker un mail de confirmation et d&#8217;avoir un retour sur paiement très rapide puisque Coinbase est initialement un service d&#8217;analyse de la block chain et qu&#8217;ils la surveillent en permanence.</p>
<p>J&#8217;ai donc fait un envoi de 0.25 BTC, ce qui équivalait à environ $50. Encore une fois, la somme est directement liée à ce que j&#8217;ai pu me permettre ce jour là. Si vous avez juste un euro à donner une fois dans l&#8217;année, c&#8217;est parfait. On s&#8217;en branle. Il y a des mois où je ne donne rien car j&#8217;ai pas un rond.</p>


feed_id: http://sametmax.com/?p=15764
title: Changement des points sur IndexError 18
uri: Changement-des-points-sur-IndexError-3-Recently-updated
url: http://sametmax.com/changement-des-points-sur-indexerror/
content:
<p>Juste pour signaler rapidement qu&#8217;on a changé la logique d&#8217;attribution de points sur indexerror.net.</p>
<p>Le réglage par défaut du site était de multiplier tous les gains de points par 10, ce qui incite les premiers utilisateurs car on a l&#8217;impression de progresser très vite.</p>
<p>Mais ça implique aussi que les points n&#8217;ont vite plus de sens : en 2 semaines j&#8217;avais cumulé plusieurs milliers de points.</p>
<p>Donc on a changé ça, et les points ont été recalculé pour que chacun ait un total plus raisonnable.</p>
<p>C&#8217;est donc tout à fait normal si vous les voyez chuter d&#8217;un coup. Max a envoyé un mail à tous les inscrits normalement, mais je mets la justification ici just in case.</p>


feed_id: http://sametmax.com/?p=15786
title: Gestion des erreurs en Python 9
uri: Gestion-des-erreurs-en-Python-Recently-updated
url: http://sametmax.com/gestion-des-erreurs-en-python/
content:
<p>Plus on code, plus on oublie ce que c&#8217;était quand on a débuté. Même moi, et pourtant je fais un gros effort pour essayer de me replonger dans cet état d&#8217;esprit.</p>
<p>Dernièrement j&#8217;ai eu plusieurs interactions qui m&#8217;ont mis un petit taquet derrière la tête :</p>
<blockquote><p>- &#8220;Mec, les exceptions, y a plein de personnes qui pigent pas.&#8221;</p>
<p>&#8211; &#8220;Nannnn, mais quand même, les exceptions&#8230;&#8221;</p>
<p>&#8211; &#8220;Si, les exceptions.&#8221;</p>
<p>&#8211; &#8220;Nan, vraiment ?&#8221;</p>
<p>&#8211; &#8220;Oui, vraiment.&#8221;</p></blockquote>
<p>Donc, back to black, et petit tour de la gestion d&#8217;erreur en Python.</p>
<p>Et de la musique.</p>
<p><span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='1170' height='689' src='http://www.youtube.com/embed/8inJtTG_DuU?version=3&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent' frameborder='0' allowfullscreen='true'></iframe></span></p>
<h2>La notion d&#8217;exception</h2>
<p>Une exception est un mécanisme d&#8217;interruption du programme utilisé pour signaler que quelque chose d&#8217;anormal est en train de se produire.</p>
<p>On les rencontre dans de nombreux cas, mais souvent, c&#8217;est dans le cadre d&#8217;erreurs. Par exemple, Python va lever une exception dans les cas suivant :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff4500;">1</span> / <span style="color: #ff4500;">0</span> <span style="color: #808080; font-style: italic;"># division par zéro</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-2-b710d87c980c&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #ff4500;">1</span> / <span style="color: #ff4500;">0</span>
<span style="color: #008000;">ZeroDivisionError</span>: integer division <span style="color: #ff7700;font-weight:bold;">or</span> modulo by zero
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> l <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> l<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># dépassement d'un tableau</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-4-3e7ce3111e95&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    l<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">IndexError</span>: <span style="color: #008000;">list</span> index out of <span style="color: #008000;">range</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'cle'</span>: <span style="color: #483d8b;">'valeur'</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nope'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># clé de dico inconnue</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-6-9d965227e4b0&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    d<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nope'</span><span style="color: black;">&#93;</span>
<span style="color: #008000;">KeyError</span>: <span style="color: #483d8b;">'nope'</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff4500;">1</span> + <span style="color: #483d8b;">&quot;banane&quot;</span> <span style="color: #808080; font-style: italic;"># opération entre types incompatibles</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-7-5147635e41b3&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #ff4500;">1</span> + <span style="color: #483d8b;">&quot;banane&quot;</span>
<span style="color: #008000;">TypeError</span>: unsupported operand <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> +: <span style="color: #483d8b;">'int'</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #483d8b;">'str'</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> nawak <span style="color: #808080; font-style: italic;"># ce module n'existe pas</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-12-c948b8798146&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #ff7700;font-weight:bold;">import</span> nawak
<span style="color: #008000;">ImportError</span>: No module named nawak
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'nawak'</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># le fichier n'existe pas</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-13-4d15cfd2ffd1&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'nawak'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">IOError</span>: <span style="color: black;">&#91;</span>Errno <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> No such <span style="color: #008000;">file</span> <span style="color: #ff7700;font-weight:bold;">or</span> directory: <span style="color: #483d8b;">'nawak'</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nawak<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># la variable n'existe pas</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-15-f47a27cedc12&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>nawak<span style="color: black;">&#41;</span>
<span style="color: #008000;">NameError</span>: name <span style="color: #483d8b;">'nawak'</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> n a w a k <span style="color: #808080; font-style: italic;"># erreur de syntaxe</span>
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-16-532bf025442e&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span>
    n a w a k <span style="color: #808080; font-style: italic;"># erreur de syntaxe</span>
      ^
<span style="color: #008000;">SyntaxError</span>: invalid syntax
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># la valeur passée n'a aucun sens</span>
&nbsp;
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-17-b3c3f4515dd4&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">ValueError</span>: invalid literal <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">with</span> base <span style="color: #ff4500;">10</span>: <span style="color: #483d8b;">'a'</span></pre></td></tr></table></div>

<p>De base, il y a un paquet d&#8217;exceptions en Python, et celles fournies par défaut sont listées <a href="https://docs.python.org/2/library/exceptions.html#exceptions.TypeError">ici</a>.</p>
<p>Malgré l&#8217;abondance de ces exceptions, vous pouvez remarquer un motif récurrent quand Python crash et affiche l&#8217;erreur :</p>
<pre>Gros pâté de texte.
Gros pâté de texte.
Gros pâté de texte.
NomDeLExceptionError: description de l'erreur.</pre>
<p>En effet, non seulement une exception interrompt le programme, mais elle collecte des informations sur la source de l&#8217;erreur afin qu&#8217;au moment où ça crash, le développeur ait de quoi déboguer.</p>
<p>Une exception va donc normalement déclencher un affichage à la fin avec toutes ces infos, et sur la dernière ligne, le type de l&#8217;exception (ValueError, IndexError, etc) ainsi qu&#8217;une description de ce qui a causé l&#8217;erreur.</p>
<p>Néanmoins, le plus intéressant est ce qu&#8217;il y a au dessus : le gros pâté de texte. C&#8217;est ce qu&#8217;on appelle une stack trace, et ça représente la pile d&#8217;appels qui ont amené à cette erreur. Chaque ligne de la stack trace va vous donner le chemin d&#8217;un fichier de code, et une ligne.</p>
<p>Une erreur se lit donc à l&#8217;envers, de bas en haut.</p>
<p>Vous lisez d&#8217;abord le nom de l&#8217;erreur et sa cause, puis, vous remontez la stack trace ligne à ligne, pour essayer de trouver quelle ligne de quel fichier de code vous devez déboguer.</p>
<p>Par exemple, si vous avez un fichier <code>wololo.py</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> une_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">1</span> / <span style="color: #ff4500;">0</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> une_autre_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    une_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
une_autre_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Lancer ce script va vous pondre :</p>
<pre>
Traceback (most recent call last):
  File "wololo.py", line 7, in <module>
    une_autre_fonction()
  File "wololo.py", line 5, in une_autre_fonction
    une_fonction()
  File "wololo.py", line 2, in une_fonction
    return 1 / 0
ZeroDivisionError: integer division or modulo by zero
</pre>
<p>On le lit de bas en haut :</p>
<pre>ZeroDivisionError: integer division or modulo by zero</pre>
<p>Ok, donc c&#8217;est une erreur de division par 0.</p>
<pre>  File "wololo.py", line 2, in une_fonction
    return 1 / 0</pre>
<p>Elle a lieu dans mon fichier <code>wololo.py</code> à la ligne 2.</p>
<p>Mais visiblement, ce qui déclenche tout le bordel, c&#8217;est que la fonction contenant cette ligne est appelé à la ligne 5 :</p>
<pre>
  File "wololo.py", line 5, in une_autre_fonction
    une_fonction()</pre>
<p>Qui est elle même appelée à la ligne 7 :</p>
<pre>
  File "wololo.py", line 7, in <module>
    une_autre_fonction()
</pre>
<p>Avec ces infos, on peut prendre une décision : aller ligne 2 pour corriger un bug, ou aller ligne 5, ou 7 pour retirer l&#8217;appel qui cause le déclenchement du code fautif.</p>
<p>Dans ce cas, vous pourriez vous dire qu&#8217;il faut retirer la division par 0, et que les premières ligne de la stack trace ne servent à rien.</p>
<p>Mais imaginez que je change mon code :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> une_fonction<span style="color: black;">&#40;</span>diviseur<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">1</span> / diviseur
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> une_autre_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    une_fonction<span style="color: black;">&#40;</span>diviseur<span style="color: #66cc66;">=</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
une_autre_fonction<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>A ce moment là, mon stack trace sera :</p>
<pre>Traceback (most recent call last):
  File "wololo.py", line 7, in <module>
    une_autre_fonction()
  File "wololo.py", line 5, in une_autre_fonction
    une_fonction(diviseur=0)
  File "wololo.py", line 2, in une_fonction
    return 1 / diviseur
ZeroDivisionError: integer division or modulo by zero</pre>
<p>Et là, on ne veut pas changer la ligne 2, on veut changer la ligne 5, car c&#8217;est ce paramètre qui fait qu&#8217;à la ligne 2 on a une division par 0.</p>
<p>La stack trace permet donc de remonter la chaîne de causalité de vos erreurs.</p>
<h2>Lever ses propres exceptions</h2>
<p>Quand une exception est activée, on dit qu&#8217;elle est &#8220;levée&#8221;.</p>
<p>Python va lever des exceptions de lui-même, par exemple en cas d&#8217;erreurs, mais on peut aussi lever soi-même des exceptions en faisant <code>raise NomDeLException("Message")</code>.</p>
<p>Par exemple, vous avez une fonction qui n&#8217;accepte en paramètre que comme valeur 1, 2 ou 3. Vous savez que si un utilisateur rentre quelque chose d&#8217;autre, ça va tout faire merder.</p>
<p>Vous pouvez faire ceci :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> votre_super_fonction<span style="color: black;">&#40;</span>param<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> param <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">ValueError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;'param' can only be either 1, 2 or 3&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># reste du code</span></pre></td></tr></table></div>

<p>Ainsi, si quelqu&#8217;un passe un mauvais paramètre, il est immédiatement alerté :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> votre_super_fonction<span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-3-bcd6e8653c83&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    votre_super_fonction<span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-2-46fc7cd18c42&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> votre_super_fonction
    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">ValueError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;'param' can only be either 1, 2 or 3&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">ValueError</span>: <span style="color: #483d8b;">'param'</span> can only be either <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff4500;">3</span></pre></td></tr></table></div>

<p>Attention : le message ne peut pas contenir de caractères non-ASCII. Oubliez les accents.</p>
<h2>Attraper une exception</h2>
<p>Les exceptions ne sont pas un simple mécanisme de debuggage. Elles servent d&#8217;abord et avant tout à gérer les cas exceptionnels, et on peut donc les détecter, et réagir quand elles surviennent, à l&#8217;aide de l&#8217;instruction <code>try/except</code>.</p>
<p>Cela s&#8217;utilise en enrobant les lignes qui peuvent lever une exception :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #808080; font-style: italic;"># lignes qui peuvent</span>
        <span style="color: #808080; font-style: italic;"># lever une exception</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> NomException:
        <span style="color: #808080; font-style: italic;"># faire un truc si l'exception se déclenche</span></pre></td></tr></table></div>

<p>Quand vous attrapez une exception, le programme ne plante pas. A la place, le bloc <code>except</code> correspondant au nom de l&#8217;exception est appelée.</p>
<p>Bien entendu, si une exception qui ne porte pas ce nom est levée, le programme plante.</p>
<p>Par exemple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #808080; font-style: italic;"># i est définit plus haut</span>
    personnages <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'iron'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'super'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'bat'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'clepto'</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        resultat <span style="color: #66cc66;">=</span> personnages<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
    <span style="color: #808080; font-style: italic;"># i est plus grand que la taille du tableau</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span>:
        resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Si <code>i</code> est plus grand que la taille de la liste, Python va lever une <code>IndexError</code>, qui sera attrapée. Le programme ne plantera pas, et <code>resultat</code> sera égal à <code>None</code>.</p>
<p>Si <code>i</code> est de type string, Python va lever une <code>TypeError</code>, et le programme va planter.</p>
<p>Cela suppose de savoir le nom de l&#8217;erreur qu&#8217;on veut gérer. Je recommande donc de tester le cas foireux dans le shell auparavant.</p>
<p>On peut gérer plusieurs exceptions avec un seul bloc :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span> / i<span style="color: black;">&#93;</span>
    <span style="color: #808080; font-style: italic;"># est exécuté pour ces deux exceptions</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">ZeroDivisionError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
    <span style="color: #808080; font-style: italic;"># est exécuté pour cette exception</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyError</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Qui est le bâtard qui a remplacé ma &quot;</span>
              <span style="color: #483d8b;">&quot;liste par un dico dans mon dos ?&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<h2>Hiérarchie des exceptions</h2>
<p>Les exceptions sont des classes. Et si vous avez lu notre <a href="http://sametmax.com/le-guide-ultime-et-definitif-sur-la-programmation-orientee-objet-en-python-a-lusage-des-debutants-qui-sont-rassures-par-les-textes-detailles-qui-prennent-le-temps-de-tout-expliquer-partie-1/">dossier sur la POO</a>, vous savez que les classes peuvent hériter d&#8217;autres classes.</p>
<p>C&#8217;est le cas des exceptions. Celles intégrées à Python suivent la hiérarchie suivante :</p>
<pre>
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- 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
</pre>
<p>Par exemple, <code>IndexError</code> et <code>KeyError</code> héritent toutes les deux de <code>LookupError</code>.</p>
<p>Donc si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">LookupError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Vous attrapez à la fois les exceptions de type <code>IndexError</code> et <code>KeyError</code>.</p>
<p><code>LookupError</code> hérite de <code>Exception</code>, dont hérite la plupart des exceptions en Python. Donc si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span> / i<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Vous allez attraper <code>LookupError</code>, <code>IndexError</code>, <code>ZeroDivisionError</code> et probablement tout un tas de trucs auxquels vous n&#8217;avez pas pensé ce qui peut potentiellement un jour masquer un bug dans votre programme.</p>
<p>Donc <strong>gérez toujours l&#8217;erreur au plus proche de la logique de votre programme</strong>.</p>
<p>Il est d&#8217;ailleurs possible de dire à Python &#8220;tu m&#8217;attrapes tout&#8221; en omettant le nom de l&#8217;exception :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span> / i<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>C&#8217;est généralement une mauvaise idée car si il arrive une erreur que vous n&#8217;avez pas prévue, la close <code>except</code> s&#8217;activera, masquant l&#8217;erreur, et ne vous donnera jamais la chance de découvrir le problème.</p>
<p>Sachez également que vous n&#8217;êtes pas limité à la hiérarchie offerte par Python. Vous pouvez créer vos propres exceptions en héritant d&#8217;une des exceptions existantes de Python :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> MonProjetError<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> MonTraitementError<span style="color: black;">&#40;</span>MonProjetError<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></td></tr></table></div>

<p>C&#8217;est généralement une bonne idée quand vous créez une lib et que vous voulez permettre aux utilisateurs de votre bibliothèque de pouvoir filtrer les exceptions levées par votre code uniquement.</p>
<p>Néanmoins, dans ce cas, choisissez intelligemment les parents de vos exceptions personnalisées. Chaque exception de Python est porteuse de sens. <code>TypeError</code> est levée pour une erreur de type, <code>IOError</code> pour une erreur d&#8217;entrée/sortie, etc. Il est logique qu&#8217;un développeur s&#8217;attende à pouvoir les attraper selon ce sens.</p>
<p>Heureusement, on peut hériter de plusieurs exceptions :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> MonProjetError<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> MonTraitementError<span style="color: black;">&#40;</span>MonProjetError<span style="color: #66cc66;">,</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></td></tr></table></div>

<p>Du coup, si quelqu&#8217;un essaye d&#8217;attraper <code>MonTraitementError</code> ou <code>TypeError</code> ou <code>MonProjetError</code> selon ce qu&#8217;il désire exprimer, ça marchera.</p>
<p>En effet, les exceptions sont une forme d&#8217;expression :</p>
<ul>
<li>Celui qui lève l&#8217;exception dit explicitement ce qui peut merder : quand on lit son code, on comprend les cas d&#8217;erreurs.</li>
<li>Celui qui l&#8217;attrape dit explicitement ce qu&#8217;il veut gérer : quand on lit son code, on comprend l&#8217;objectif.</li>
<li>Python dit explicitement ce qui a foiré. Quand on lit la stack trace, on comprend ce qui a merdé.</li>
</ul>
<p><strong>Vous communiquez en utilisant des exceptions entre développeurs et utilisateurs du code.</strong></p>
<h2>Finally et else</h2>
<p><code>try/except</code> peut être complété par deux autres mots clés : <code>finally</code> et <code>else</code>.</p>
<p><code>else</code> est le bloc exécuté si aucune exception n&#8217;est levée :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span> / i<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">ZeroDivisionError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyError</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Qui est le bâtard qui a remplacé ma &quot;</span>
              <span style="color: #483d8b;">&quot;liste par un dico dans mon dos ?&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Bon en fait tout va bien'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><code>finally</code> est un bloc qui est exécuté après que tous les autres blocs aient été exécutés, peu importe qu&#8217;il y ait eu une exception ou non, et <strong>même si le programme crash</strong>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> personnages<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span> / i<span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">ZeroDivisionError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyError</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Qui est le bâtard qui a remplacé ma &quot;</span>
              <span style="color: #483d8b;">&quot;liste par un dico dans mon dos ?&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">finally</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Rosebud !'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Dans notre cas, peu importe ce qui se passe dans le bloc <code>try/except</code>, <code>Rosebud !</code> est toujours affiché.</p>
<p><code>finally</code> n&#8217;est pas à l&#8217;épreuve des balles, si on crash l’interpréteur violemment (ou que vous débranchez la prise du serveur :)), il ne vous sauvera pas. Mais il permet de gérer la plupart des cas extrêmes.</p>
<p>Ah, oui, au fait, si vous utilisez <code>finally</code>, <code>except</code> n&#8217;est pas obligatoire.</p>
<h2>Quand utiliser try, except, else et finally ?</h2>
<p>On utilisera <code>try/except</code> d&#8217;abord et avant tout pour gérer les erreurs sur laquelle on a pas de controle.</p>
<p>Par exemple, vous téléchargez une document depuis le Web :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier_recu<span style="color: #66cc66;">,</span> headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://www.sudinfo.be/sites/default/files/imagecache/pagallery_450x300/1365338424_B9765144Z.1_20121219124926_000_GOJDROM6.1-0.png'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ca va marcher la plupart du temps. Et puis un jour, le réseau va sauter, et ça va plus marcher :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier_recu<span style="color: #66cc66;">,</span> headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://www.sudinfo.be/sites/default/files/imagecache/pagallery_450x300/1365338424_B9765144Z.1_20121219124926_000_GOJDROM6.1-0.png'</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;ipython-input-10-0f41d15585f0&gt;&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    fichier_recu<span style="color: #66cc66;">,</span> headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://www.sudinfo.be/sites/default/files/imagecache/pagallery_450x300/1365338424_B9765144Z.1_20121219124926_000_GOJDROM6.1-0.png'</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">178</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> urlretrieve
    <span style="color: #ff7700;font-weight:bold;">with</span> contextlib.<span style="color: black;">closing</span><span style="color: black;">&#40;</span>urlopen<span style="color: black;">&#40;</span>url<span style="color: #66cc66;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> fp:
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">153</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> urlopen
    <span style="color: #ff7700;font-weight:bold;">return</span> opener.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span>url<span style="color: #66cc66;">,</span> data<span style="color: #66cc66;">,</span> timeout<span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">455</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">open</span>
    response <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>._open<span style="color: black;">&#40;</span>req<span style="color: #66cc66;">,</span> data<span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">473</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> _open
    <span style="color: #483d8b;">'_open'</span><span style="color: #66cc66;">,</span> req<span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">433</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> _call_chain
    result <span style="color: #66cc66;">=</span> func<span style="color: black;">&#40;</span>*args<span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1258</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> http_open
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">do_open</span><span style="color: black;">&#40;</span>http.<span style="color: black;">client</span>.<span style="color: black;">HTTPConnection</span><span style="color: #66cc66;">,</span> req<span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;/usr/lib/python3.4/urllib/request.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">1235</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> do_open
    <span style="color: #ff7700;font-weight:bold;">raise</span> URLError<span style="color: black;">&#40;</span>err<span style="color: black;">&#41;</span>
URLError: <span style="color: #66cc66;">&lt;</span>urlopen error <span style="color: black;">&#91;</span>Errno -<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> Name <span style="color: #ff7700;font-weight:bold;">or</span> service <span style="color: #ff7700;font-weight:bold;">not</span> known<span style="color: #66cc66;">&gt;</span></pre></td></tr></table></div>

<p>On va donc gérer l&#8217;exception (et beaucoup d&#8217;autres, le réseau ça foire tout le temps) :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    fichier_recu<span style="color: #66cc66;">,</span> headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://www.sudinfo.be/sites/default/files/imagecache/pagallery_450x300/1365338424_B9765144Z.1_20121219124926_000_GOJDROM6.1-0.png'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">URLError</span>:
    <span style="color: #808080; font-style: italic;"># faire un truc</span></pre></td></tr></table></div>

<p>Parmi les choses à faire : réessayer plus tard, tenter de redémarrer la carte réseau, changer d&#8217;URL&#8230;</p>
<p>Un autre raison d&#8217;utiliser <code>try/except</code> est pour enregistrer une trace des erreurs.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    url <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'http://www.sudinfo.be/sites/default/files/imagecache/pagallery_450x300/1365338424_B9765144Z.1_20121219124926_000_GOJDROM6.1-0.png'</span>
    fichier_recu<span style="color: #66cc66;">,</span> headers <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">request</span>.<span style="color: black;">urlretrieve</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">URLError</span>:
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/errors.log'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'a'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;L'URL '%s' est inacessible&quot;</span> % url<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>On peut le faire avec le module <code>logging</code>, ou envoyer un mail ou un SMS d&#8217;alerte&#8230;</p>
<p>Proposer un comportement par défaut est aussi très courant.</p>
<p>Par exemple, vous voulez récupérer le premier élément d&#8217;une liste, mais si la liste est vide, récupérer <code>None</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    resultat <span style="color: #66cc66;">=</span> liste<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span>:
    resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Ce cas d&#8217;usage est typique de Python. Dans d&#8217;autres langage, on regarderait si le tableau est vide :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> liste:
    resultat <span style="color: #66cc66;">=</span> liste<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>C&#8217;est typiquement la philosophie Java : &#8220;Watch before you leap&#8221; (WBYL). Soit &#8220;Regardez où vous mettez les pieds&#8221;.</p>
<p>En Python, la philosophie est &#8220;It&#8217;s easier to ask for forgiveness than permission&#8221; (EAFP). Soit &#8220;il est plus facile de demander pardon que la permission&#8221;.</p>
<p>La raison est que les exceptions sont très rapides en Python, et permettent de gérer plein de cas d&#8217;un coup.</p>
<p>Par exemple, dans le cas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> conteneur:
    resultat <span style="color: #66cc66;">=</span> conteneur<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Que se passe-t-il si conteneur peut être un dictionnaire ou une liste ? C&#8217;est possible en Python du fait du <a href="http://sametmax.com/quest-ce-que-le-duck-typing-et-a-quoi-ca-sert/">duck typing</a>.</p>
<p>Il faut tester deux cas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> conteneur <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">in</span> conteneur:
    resultat <span style="color: #66cc66;">=</span> conteneur<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Avec une exception, on teste un seul cas :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    resultat <span style="color: #66cc66;">=</span> conteneur<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">LookupError</span>:
    resultat <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span></pre></td></tr></table></div>

<p>Là c&#8217;est un cas simple, mais sur des cas complexes comme les fichiers, c&#8217;est très utile :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    fichier <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/fichier'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">OSError</span>:
    <span style="color: #808080; font-style: italic;"># gérer l'erreur</span></pre></td></tr></table></div>

<p>Si je devais faire ça avec des <code>if</code>, il faudrait :</p>
<ul>
<li>Vérifier que le fichier existe.</li>
<li>Vérifier que le fichier est un fichier et non un dossier.</li>
<li>Vérifier que j&#8217;ai les permissions d&#8217;écrire sur le fichier.</li>
<li>Vérifier que j&#8217;ai les permissions de traverser les dossiers parents.</li>
<li>Vérifier que personne n&#8217;a ouvert le fichier en écriture avant.</li>
</ul>
<p>C&#8217;est relou. Mais en prime, entre chaque vérification du <code>if</code> s&#8217;écoule quelques nanosecondes durant lequelles l&#8217;état de mon fichier a pu changer. Un autre programme a pu changer les permissions, créer un fichier avec le même nom, etc. Arrivé à la fin du <code>if</code>, on n&#8217;a pas la garantie que les vérifications du début du <code>if</code> sont toujours d&#8217;actualité.</p>
<p><code>try/except</code> évite ce problème qu&#8217;on appelle des &#8220;race conditions&#8221; : on essaye d&#8217;abord, et ensuite si ça foire, on analyse pourquoi. Comme en drague.</p>
<p>Enfin on va utiliser <code>finally</code> pour faire du nettoyage : fermer un fichier, fermer une connexion à une base de données, une socket, supprimer un fichier temporaire. Bref, tout ce qu&#8217;on veut qui arrive, même si notre code se vautre.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    fichier <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/fichier'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">OSError</span>:
    <span style="color: #808080; font-style: italic;"># gérer l'erreur</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #808080; font-style: italic;"># faire un truc avec le fichier</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># on essaye toujours de fermer notre fichier</span>
<span style="color: #ff7700;font-weight:bold;">finally</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        fichier.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># le fichier n'a jamais été ouvert et</span>
    <span style="color: #808080; font-style: italic;"># la variable n'existe pas</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">NameError</span>:
        <span style="color: #ff7700;font-weight:bold;">pass</span></pre></td></tr></table></div>

<h2>with</h2>
<p>Comme vous avez pu le constater, gérer proprement les erreurs, ça peut devenir vite chiant. Pour cette raison, beaucoup de <a href="http://sametmax.com/les-context-managers-et-le-mot-cle-with-en-python/">context managers</a> servent à gérer les cas les plus courants.</p>
<p>Typiquement :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    fichier <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/fichier'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">OSError</span>:
    <span style="color: #808080; font-style: italic;"># gérer l'erreur</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #808080; font-style: italic;"># faire un truc avec le fichier</span>
<span style="color: #ff7700;font-weight:bold;">finally</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        fichier.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">NameError</span>:
        <span style="color: #ff7700;font-weight:bold;">pass</span></pre></td></tr></table></div>

<p>Peut être remplacé par :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/tmp/fichier'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> fichier:
        <span style="color: #808080; font-style: italic;"># faire un truc avec le fichier</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">OSError</span>:
    <span style="color: #808080; font-style: italic;"># gérer l'erreur</span></pre></td></tr></table></div>

<p>Ce qui est quand même vachement plus court. Le context manager va s&#8217;occuper de la fermeture du fichier pour nous proprement. Cet article est déjà long, donc je ne vais pas rentrer en détail sur <code>with</code>, mais sachez que beaucoup d&#8217;objets qui demandent une fermeture peuvent être traités comme ça.</p>
<h2>Bubbling</h2>
<p>Une chose qui échappe généralement aux débutants quand ils commencent à utiliser les exceptions, c&#8217;est qu&#8217;elles bubblent, c&#8217;est à dire qu&#8217;elles remontent comme une bulle, de bloc en bloc, jusqu&#8217;à la racine du programme.</p>
<p>Si j&#8217;ai :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> truc:
    <span style="color: #ff7700;font-weight:bold;">if</span> machin:
        <span style="color: #ff7700;font-weight:bold;">for</span> bidule <span style="color: #ff7700;font-weight:bold;">in</span> chose:
            <span style="color: #ff7700;font-weight:bold;">raise</span> MaisAieuuuuuError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ca fait mal t'es con&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Mon programme ne va PAS planter à la ligne <code>raise MaisAieuuuuuError("Ca fait mal t'es con")</code>.</p>
<p>A la place, l&#8217;erreur va remonter en dehors de la boucle. Si elle n&#8217;est pas attrapée, elle va remonter en dehors du premier <code>if</code>. Si elle n&#8217;est pas attrapée, elle va remonter en dehors du second <code>if</code>, et enfin, si elle vraiment, mais alors vraiment pas attrapée, Python va crasher, et montrer une belle stack trace.</p>
<p>Ça veut dire que vous pouvez arrêter l&#8217;exception à plusieurs endroits dans le programme :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> truc:
    <span style="color: #ff7700;font-weight:bold;">if</span> machin:
        <span style="color: #ff7700;font-weight:bold;">for</span> bidule <span style="color: #ff7700;font-weight:bold;">in</span> chose:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> MaisAieuuuuuError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ca fait mal t'es con&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">except</span> MaisAieuuuuuError:
                <span style="color: #808080; font-style: italic;"># faire un truc</span></pre></td></tr></table></div>

<p>Dans ce cas, la boucle va continuer à tourner après la première erreur, et faire un <code>try/except</code> à chaque tour de boucle.</p>
<p>Mais si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> truc:
    <span style="color: #ff7700;font-weight:bold;">if</span> machin:
        <span style="color: #ff7700;font-weight:bold;">try</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> bidule <span style="color: #ff7700;font-weight:bold;">in</span> chose:
                <span style="color: #ff7700;font-weight:bold;">raise</span> MaisAieuuuuuError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ca fait mal t'es con&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> MaisAieuuuuuError:
            <span style="color: #808080; font-style: italic;"># faire un truc</span></pre></td></tr></table></div>

<p>A la première erreur, la boucle est interrompue définitivement. Par contre la condition <code>if machin</code> va continuer sa route.</p>
<p>Mais si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> truc:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> machin:
            <span style="color: #ff7700;font-weight:bold;">for</span> bidule <span style="color: #ff7700;font-weight:bold;">in</span> chose:
                <span style="color: #ff7700;font-weight:bold;">raise</span> MaisAieuuuuuError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ca fait mal t'es con&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> MaisAieuuuuuError:
        <span style="color: #808080; font-style: italic;"># faire un truc</span></pre></td></tr></table></div>

<p>La condition <code>if machin</code> est définitivement interrompue.</p>
<p>Et si vous faites :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> truc:
        <span style="color: #ff7700;font-weight:bold;">if</span> machin:
            <span style="color: #ff7700;font-weight:bold;">for</span> bidule <span style="color: #ff7700;font-weight:bold;">in</span> chose:
                <span style="color: #ff7700;font-weight:bold;">raise</span> MaisAieuuuuuError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Ca fait mal t'es con&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> MaisAieuuuuuError:
    <span style="color: #808080; font-style: italic;"># faire un truc</span></pre></td></tr></table></div>

<p>Là, tout le programme est interrompu. Ca ne plantera pas, mais ça ne fera plus rien.</p>
<p>Il faut donc choisir soigneusement où attraper l&#8217;exception selon la partie du programme qu&#8217;on souhaite interrompre.</p>
<h2>Manipuler l&#8217;exception attrapée</h2>
<p>Les exceptions sont des objets complets. On peut les récupérer avec le mot clés <code>as</code> et analyser leur contenu.</p>
<p>Exemple :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nawak&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span> <span style="color: #ff7700;font-weight:bold;">as</span> e:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;args: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">args</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;errno: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: #dc143c;">errno</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filename: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">filename</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;strerror: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">strerror</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">## args:  (2, 'No such file or directory')</span>
<span style="color: #808080; font-style: italic;">## errno:  2</span>
<span style="color: #808080; font-style: italic;">## filename:  nawak</span>
<span style="color: #808080; font-style: italic;">## strerror:  No such file or directory</span></pre></td></tr></table></div>

<p>Il est même possible de les lever à nouveau après :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nawak&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span> <span style="color: #ff7700;font-weight:bold;">as</span> e:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;args: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">args</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;errno: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: #dc143c;">errno</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filename: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">filename</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;strerror: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">strerror</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">raise</span> e</pre></td></tr></table></div>

<p><code>raise</code> appelé sans argument lève de toute façon automatiquement l&#8217;exception en cours. Mais il est possible de lever une autre exception :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    f <span style="color: #66cc66;">=</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;nawak&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IOError</span> <span style="color: #ff7700;font-weight:bold;">as</span> e:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;args: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">args</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;errno: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: #dc143c;">errno</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filename: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">filename</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;strerror: &quot;</span><span style="color: #66cc66;">,</span> e.<span style="color: black;">strerror</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">raise</span> MonError<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;T'as encore oublie ton classeur Man&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<h2>Erreur à la sortie de l&#8217;interpréteur</h2>
<p>Il est possible d&#8217;attraper n&#8217;importe quelle exception non gérée juste avant qu&#8217;elle fasse crasher le programme, sans avoir à mettre tout son code dans un gros <code>try/except</code>.</p>
<p>Il faut définir une fonction qui accepte 3 arguments que sont la classe de l&#8217;exception, l&#8217;instance de l&#8217;exception et l&#8217;objet traceback :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> attrapez_les_tous<span style="color: black;">&#40;</span><span style="color: #008000;">type</span><span style="color: #66cc66;">,</span> value<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">traceback</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Pokemon !&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Ensuite il faut l&#8217;attacher au module <code>sys</code> avec le bon nom :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">excepthook</span> <span style="color: #66cc66;">=</span> attrapez_les_tous</pre></td></tr></table></div>

<p>Et hop :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff4500;">1</span> / <span style="color: #ff4500;">0</span>
Pokemon <span style="color: #66cc66;">!</span></pre></td></tr></table></div>

<p>Alors, c&#8217;est certain que si vous faites ça, vous avez intérêt à savoir ce que vous branlez car vous pouver tuer le debuggage. Ou alors créer un super moyen de logger toute erreur sur un process séparé qui vous le présente dans une belle interface Web. Au choix.</p>
<h2>Les exceptions en dehors des erreurs</h2>
<p>Les exceptions sont la pour gérer des cas exceptionnels, et pas forcément une erreur. Par exemple, la boucle <code>for</code> utilise les exceptions pour savoir quand s&#8217;arrêter. En effet elle attend que l&#8217;itérateur qu&#8217;elle utilise lève <code>StopIteration</code> :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> iterateur <span style="color: #66cc66;">=</span> <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span>
---------------------------------------------------------------------------
<span style="color: #008000;">StopIteration</span>                             Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>ipython-input-<span style="color: #ff4500;">11</span>-d90e1e04a685<span style="color: #66cc66;">&gt;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
----<span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">1</span> next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">StopIteration</span>:</pre></td></tr></table></div>

<p>Donc quand on fait ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>En fait, la boucle fait un truc comme ça :</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="python" style="font-family:monospace;">iterateur <span style="color: #66cc66;">=</span> <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>next<span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">StopIteration</span>:
        <span style="color: #ff7700;font-weight:bold;">break</span></pre></td></tr></table></div>

<p>Les exceptions en Python, c&#8217;est une grande histoire d&#8217;amour.</p>


