<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>E-vidence</title>
	<atom:link href="http://www.e-vidence.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.e-vidence.net</link>
	<description>La petite dose d'ergonomie hebdomadaire</description>
	<pubDate>Tue, 31 Aug 2010 11:31:47 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Résoudre le Git &#8220;error: src refspec [branch] does not match any&#8221;</title>
		<link>http://www.e-vidence.net/?p=457</link>
		<comments>http://www.e-vidence.net/?p=457#comments</comments>
		<pubDate>Tue, 31 Aug 2010 08:51:50 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Développement]]></category>

		<category><![CDATA[error]]></category>

		<category><![CDATA[git]]></category>

		<category><![CDATA[refspec]]></category>

		<category><![CDATA[remote]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=457</guid>
		<description><![CDATA[Il peut y avoir plusieurs raisons à ce mystérieux laïus:
<ul>
	<li>
<p style="margin-bottom: 0cm;">Vous avez oublié de faire 'add' 	ou 'commit' et fait un 'push' directement</p>
</li>
	<li>Vous n'avez pas de référence vers votre 'remote'</li>
</ul>
Le premier est facile à résoudre, le second est moins intuitif.]]></description>
			<content:encoded><![CDATA[<p>Il peut y avoir plusieurs raisons à ce mystérieux laïus:</p>
<ul>
<li> Vous avez oublié de faire &#8216;add&#8217; 	ou &#8216;commit&#8217; et fait un &#8216;push&#8217; directement</li>
<li>Vous n&#8217;avez pas de référence vers votre &#8216;remote&#8217;</li>
</ul>
<p>Le premier est facile à résoudre, le second est moins intuitif.<br />
Un &#8216;remote&#8217; est une référence vers un autre depot. Si vous travaillez avec plusieurs dépôts en parallèle, et que vous souhaitez faire &#8216;pull&#8217; depuis le premier, puis &#8216;push&#8217; vers le second, alors il faut ajouter cette référence puis une référence vers une branche. Cela donne:</p>
<pre>git remote add new_repo git://path/to/new/repo # on ajoute le nouveau remote
git fetch new_repo # on met à jour les références locales
git checkout -b remote_master new_repo/master # créer 1 branch depuis son master
git merge origin/master # on merge les deux master
git push new_repo master # on push vers le remote</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=457</wfw:commentRss>
		</item>
		<item>
		<title>Connecter son Motorola Droid (Milestone) à Ubuntu Karmic 9.10</title>
		<link>http://www.e-vidence.net/?p=454</link>
		<comments>http://www.e-vidence.net/?p=454#comments</comments>
		<pubDate>Sat, 19 Jun 2010 23:04:00 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=454</guid>
		<description><![CDATA[C'est censé être simple mais comme d'habitude, il y a 500 combinaisons possibles. Pour vous éviter de les essayer toutes.]]></description>
			<content:encoded><![CDATA[<p>C&#8217;est censé être simple mais comme d&#8217;habitude, il y a 500 combinaisons possibles. Pour vous éviter de les essayer toutes :</p>
<p><code>sudo gedit /etc/udev/rules.d/51-android.rules </code></p>
<p>Mettre la ligne:</p>
<p><code>SUBSYSTEM=="usb", ATTRS{idVendor}=="22b8", MODE="0666"</code></p>
<p>Redemarrer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=454</wfw:commentRss>
		</item>
		<item>
		<title>Revenir en arrière avec Git</title>
		<link>http://www.e-vidence.net/?p=443</link>
		<comments>http://www.e-vidence.net/?p=443#comments</comments>
		<pubDate>Tue, 30 Mar 2010 11:50:47 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Développement]]></category>

		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=443</guid>
		<description><![CDATA[Si vous avez lu le <a href="http://www.e-vidence.net/?p=430">tuto précédent</a>, Git ne vous fait plus penser à une version en ligne de commande d'un écarteleur. Vous savez comment sauvegarder votre code dans Git, et comprenez comment ça marche, mais la partie la plus intéressante reste à venir.

Nous allons voir maintenant comment récupérer une ancienne version du code et comment se déplacer dans l'historique.]]></description>
			<content:encoded><![CDATA[<p>Si vous avez lu le <a href="http://www.e-vidence.net/?p=430">tuto précédent</a>, Git ne vous fait plus penser à une version en ligne de commande d&#8217;un écarteleur. Vous savez comment sauvegarder votre code dans Git, et comprenez comment ça marche, mais la partie la plus intéressante reste à venir.</p>
<p>Nous allons voir maintenant comment récupérer une ancienne version du code et comment se déplacer dans l&#8217;historique.</p>
<p>Pour faire ce tuto, vous devrez :</p>
<ul>
<li>Avoir fait le <a href="http://www.e-vidence.net/?p=430">tuto précédent</a>.</li>
<li>Travailler sa souplesse d&#8217;esprit, car ce que l&#8217;on va voir n&#8217;a rien à voir avec ce que vous aviez probablement appris avec des outils type SVN.</li>
</ul>
<p>Temps de lecture : 1h</p>
<h3>Découvrez les branches</h3>
<p>Hein ? Les branches ? Mais on ne devait pas parler de restauration de document avant de faire des branches ?</p>
<p>Rassurez vous, on ne vas pas créer ni changer de branche, on va juste expliquer ce que c&#8217;est.</p>
<p>De manière étonnante, on ne peut pas faire du travail sérieux dans Git sans comprendre comment fonctionnent les branches car :</p>
<ul>
<li>On travaille dès le début sur une branche.</li>
<li>Les opérations de déplacement utilisent la notion de branche.</li>
<li>Les branches ne sont probablement pas du tout ce que vous croyez.</li>
</ul>
<p>En vérité, les branches ne sont pas des branches d&#8217;un arbre virtuel comme par exemple sur SVN. Elles sont de simples marqueurs, au même titre que HEAD mais avec une fonction différente. Ce sont des panneaux qui indiquent « cette partie du travail avance à partir d&#8217;ici ».</p>
<p>Par exemple, si vous travaillez sur une version Linux et une version Mac de votre programme, vous pouvez avoir avez deux branches, « linux-version » et « mac-version », ainsi disposées :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git-branch.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git-branch.png" alt="" title="git-branch" width="500" height="226" class="aligncenter size-full wp-image-444" /></a></p>
<p>Attention cependant, une branche n&#8217;est pas une succession de changesets.</p>
<p>Ainsi, la divergence de l&#8217;historique qui inclut « Nouveau changeset » et « Finalement le TODO est bien comme cela » n&#8217;est pas la branche « linux-version ». C&#8217;est juste une succession de changesets. La branche « linux-version », c&#8217;est uniquement la partie verte sur le schéma, c&#8217;est un panneau qui pointe sur un changeset pour dire « la branche est ici ».</p>
<p>Ainsi, on peut très bien avoir deux branches sur un historique linéaire :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git-branch-lineaire.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git-branch-lineaire.png" alt="" title="git-branch-lineaire" width="500" height="365" class="aligncenter size-full wp-image-445" /></a></p>
<p>La branche n&#8217;a donc rien à voir avec les directions que prend l&#8217;historique, c&#8217;est uniquement un petit point dans l&#8217;historique. Du coup la métaphore de l&#8217;arbre en prend un coup avec Git <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Autre chose : HEAD et les branches sont des concepts différents. HEAD, c&#8217;est le pointeur pour vous dire où <strong>VOUS</strong> êtes. Les branches, ce sont des pointeurs pour dire « ici se trouve une certaine version de mon code ».</p>
<p>Vous allez me dire que cela ressemble beaucoup au tags, et c&#8217;est vrai, mais la grosse différence est que les branches bougent. En particulier, si vous êtes sur une branche et que vous faites un commit, la branche se déplace sur le nouveau changeset avec vous.</p>
<p>Quand vous créez un dépôt Git, une branche est créée automatiquement et placée sur le premier changeset. C&#8217;est branche est appelée « master ». La branche « master » n&#8217;a rien de spéciale, c&#8217;est une branche comme une autre, mais elle existe depuis le début et porte toujours ce nom.</p>
<p>Ainsi, si vous avez gardé le dépôt que vous avons créé lors de notre dernier tuto, on se trouve dans la situation suivante :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git-master.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git-master.png" alt="" title="git-master" width="500" height="327" class="aligncenter size-full wp-image-446" /></a></p>
<p>Quand on est sur une branche et que l&#8217;on fait un commit, la branche est déplacée sur le nouveau changeset. Du coup, la branche « master » vous a suivi jusqu&#8217;ici. Cependant, vous devez comprendre que HEAD et la branche actuelle sont indépendants, et donc on peut bouger HEAD sans déplacer la branche.</p>
<h3>Annuler un commit avec « git commit &#8211;amend »</h3>
<p>Parfois vous ferez une sauvegarde dont vous ne voulez pas.</p>
<p>Dans ce cas, faites vos modifications telles que vous voudriez qu&#8217;elles soient, puis au lieu de faire « git commit », effectuez « git commit &#8211;amend » : le précédent commit est alors supprimé et remplacé par le précédent commit.</p>
<p>Par exemple, on ajoute « Super ! » dans text.txt, et on créé un fichier nommé proto.txt. Il reste aussi des modifications sur TODO.txt que nous n&#8217;avions pas enregistrées la dernière fois :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   test.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Untracked files:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	proto.txt</span>
no changes added to commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">&quot;git add&quot;</span> and<span style="color: #000000; font-weight: bold;">/</span>or <span style="color: #ff0000;">&quot;git commit -a&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Ajoutons nos deux modifications, mais pas la création, puis commitons :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add TODO.txt
$ git add test.txt
$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Je le sens pas ce commit&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master b415af6<span style="color: #7a0874; font-weight: bold;">&#93;</span> Je le sens pas ce commit
 <span style="color: #000000;">2</span> files changed, <span style="color: #000000;">2</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">0</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ git log
commit b415af6c2e48a8f77fc12caea380f8f7e7345b81
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Mon Mar <span style="color: #000000;">29</span> <span style="color: #000000;">16</span>:<span style="color: #000000;">55</span>:<span style="color: #000000;">10</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Je le sens pas ce commit
&nbsp;
commit 1a0633ce778044aadea23eb39cdc21fc6c949989
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">21</span>:08:04 <span style="color: #000000;">2010</span> +0000
&nbsp;
    On sauvegarde l<span style="color: #ff0000;">'index dans l'</span>historique
<span style="color: #7a0874; font-weight: bold;">&#91;</span>…<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>On s&#8217;apperçoit qu&#8217;on a oublié le fichier « proto.txt ». Si on fait un second commit, il sera pris en compte. Mais si quelqu&#8217;un récupère le code du précédent commit, il lui manquera ce fichier !</p>
<p>Annulons plutôt le précédent commit après avoir ajouté « proto.txt » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add proto.txt
$ git commit <span style="color: #660033;">--amend</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Je savais bien que j'avais oublié quelque chose&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master a9c07b1<span style="color: #7a0874; font-weight: bold;">&#93;</span> Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 proto.txt
$ git log
commit a9c07b154a6d2e3b2435fa51bbc3a920fb1652b2
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Mon Mar 29 16:55:10 2010 +0000
&nbsp;
    Je savais bien que j'</span>avais oublié quelque chose
&nbsp;
commit 1a0633ce778044aadea23eb39cdc21fc6c949989
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">21</span>:08:04 <span style="color: #000000;">2010</span> +0000
&nbsp;
    On sauvegarde l<span style="color: #ff0000;">'index dans l'</span>historique
<span style="color: #7a0874; font-weight: bold;">&#91;</span>…<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>Nous avons donc fait :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git-ammend.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git-ammend.png" alt="" title="git-ammend" width="500" height="366" class="aligncenter size-full wp-image-447" /></a></p>
<h3>Retourner à une version antérieur avec « git reset »</h3>
<p>« git reset » permet de déplacer la branche actuelle dans l&#8217;historique. Par exemple, si vous êtes au niveau de « master », vous pouvez faire pointer « master » sur un autre changeset. Par défaut, « git reset » va aussi prendre tous les changements du changesets et le mettres dans l&#8217;index, comme ça seule votre copie de travail est en décalage avec le changeset et « git status » vous donne un résultat cohérent.</p>
<p>Le HEAD est déplacé en même tant que la branche actuelle. Après un « reset », les deux pointent sur le nouveau changeset.</p>
<p>Par exemple, supposons qu&#8217;on veuille replacer la branche master à l&#8217;époque de l&#8217;ajout du .gitignore :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">$git</span> log
<span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
commit 9f2f748ecb853a1cb616b6d387f7169dac32f243
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">12</span>:<span style="color: #000000;">18</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout d<span style="color: #ff0000;">'un fichier et suppression d'</span>un autre
&nbsp;
commit e3bfc5d3457756d695bbed735ea018559d8b00cd
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">52</span>:<span style="color: #000000;">12</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
&nbsp;
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire</pre></div></div>

<p>On voit que le hash de ce changeset est e3bfc5d3457756d695bbed735ea018559d8b00cd, donc on fait un reset avec ce hash :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset e3bfc5d3457756d695bbed735ea018559d8b00cd
Unstaged changes after reset:
M	README.txt
M	TODO.txt
M	tuto.txt</pre></div></div>

<p>Notre HEAD s&#8217;est bien déplacé sur ce changeset car maintenant le log ne nous affiche plus les autres changesets :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit e3bfc5d3457756d695bbed735ea018559d8b00cd
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">52</span>:<span style="color: #000000;">12</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
&nbsp;
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire</pre></div></div>

<p>Et on peut voir que l&#8217;index a été mis à jour mais que votre copie de travail est restée intacte car « git status » nous indique des changements :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	deleted:    tuto.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Untracked files:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	proto.txt</span>
<span style="color: #666666; font-style: italic;">#	test.txt</span></pre></div></div>

<p>A ce stade vous avez peut-être envie de revenir tout en haut de l&#8217;historique, mais « git log » ne vous donne plus la référence pour le faire !</p>
<p>C&#8217;est normal, « git log » vous indique le log telle que vu par la branche courrante.  Il existe heureusement une commande qui vous permet de voir toutes les valeurs qu&#8217;on a donné à HEAD depuis le début, c&#8217;est « git reflog » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">$git</span> reflog
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>amend<span style="color: #7a0874; font-weight: bold;">&#41;</span>: Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
b415af6 HEAD@{2}: commit: Je le sens pas ce commit
1a0633c HEAD@{3}: commit: On sauvegarde l'</span>index dans l<span style="color: #ff0000;">'historique
edfb9d2 HEAD@{4}: commit: Finalement le TODO est bien comme ça
9f2f748 HEAD@{5}: commit: Ajout d'</span>un fichier et suppression d<span style="color: #ff0000;">'un autre
e3bfc5d HEAD@{6}: commit: Ajout du .gitignore
bbfc3cf HEAD@{7}: commit (initial): Ceci est un commentaire</span></pre></div></div>

<p>On voit que HEAD s&#8217;est pas mal baladé ! Le changeset qui nous intéresse est l&#8217;avant dernier (son hash abrégé est le numéro tout à gauche), et on peut y retourner avec « git reset » bien entendu :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset a9c07b1
$ git log
commit a9c07b154a6d2e3b2435fa51bbc3a920fb1652b2
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Mon Mar <span style="color: #000000;">29</span> <span style="color: #000000;">16</span>:<span style="color: #000000;">55</span>:<span style="color: #000000;">10</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
&nbsp;
commit 1a0633ce778044aadea23eb39cdc21fc6c949989
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Sat Mar 27 21:08:04 2010 +0000
&nbsp;
    On sauvegarde l'</span>index dans l<span style="color: #ff0000;">'historique
[…]</span></pre></div></div>

<h3>Les options de git reset</h3>
<p>« git reset » possède deux options  « &#8211;soft » et « &#8212; hard », qui permettent de changer son comportement.</p>
<p>« &#8211;soft » fait la même chose qu&#8217;avant, mais ne met pas à jour l&#8217;index. Vous gardez votre index d&#8217;origine, ainsi vous pouvez faire un commit directement et sauvegarder le contenu de l&#8217;index. Refaisons la même opération que précédemment avec « &#8211;soft » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset <span style="color: #660033;">--soft</span> e3bfc5d3457756d695bbed735ea018559d8b00cd
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	new file:   proto.txt</span>
<span style="color: #666666; font-style: italic;">#	new file:   test.txt</span>
<span style="color: #666666; font-style: italic;">#	deleted:    tuto.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Le status nous dit que tous les changements sont près à être sauvegardés car l&#8217;index n&#8217;a pas été modifié.</p>
<p>On retourne à notre commit final :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset a9c07b1</pre></div></div>

<p>Voyons maintenant l&#8217;option « &#8211;hard », qui elle met en plus à jour la copie de travail. Tous vos fichiers sont donc écrasés et remplacés par ceux issu du changeset vers lequel vous vous déplacez :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span>
divers  proto.txt  README.txt  test.txt  test.txt~  TODO.txt  TODO.txt~  tuto.txt
$ git reset <span style="color: #660033;">--hard</span> e3bfc5d3457756d695bbed735ea018559d8b00cd
HEAD is now at e3bfc5d Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
$ <span style="color: #c20cb9; font-weight: bold;">ls</span>
divers  README.txt  test.txt~  TODO.txt  TODO.txt~  tuto.txt</pre></div></div>

<p>Vous voyez que les fichiers de la copie de travail ont aussi changé. Du coup pour revenir à notre commit final et avoir les fichiers du commit final, il faut utiliser « &#8211;hard » également :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset <span style="color: #660033;">--hard</span> a9c07b1
HEAD is now at a9c07b1 Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose</span></pre></div></div>

<p>Vous voyez que le log des références contient maintenant la liste de nos nombreux allers-et-retours :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reflog
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">5</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">6</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">7</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">8</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>amend<span style="color: #7a0874; font-weight: bold;">&#41;</span>: Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
b415af6 HEAD@{9}: commit: Je le sens pas ce commit
1a0633c HEAD@{10}: commit: On sauvegarde l'</span>index dans l<span style="color: #ff0000;">'historique
edfb9d2 HEAD@{11}: commit: Finalement le TODO est bien comme ça
9f2f748 HEAD@{12}: commit: Ajout d'</span>un fichier et suppression d<span style="color: #ff0000;">'un autre
e3bfc5d HEAD@{13}: commit: Ajout du .gitignore
bbfc3cf HEAD@{14}: commit (initial): Ceci est un commentaire</span></pre></div></div>

<p>Le mien est sans doute un peu différent du votre car j&#8217;ai fais une ou deux coquilles durant la rédaction du tuto <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Pour récapituler :</p>
<ul>
<li>« git reset » permet de déplacer la branche courante ainsi que le HEAD. L&#8217;index est mis à jour pour refléter le nouveau changeset.</li>
<li>« &#8211;soft » permet d&#8217;éviter que l&#8217;index soit mis à jour.</li>
<li>« &#8211;hard » permet de mettre à jour aussi la copie de travail.</li>
<li>« git reflog » permet de voir tout l&#8217;historique des références de HEAD (c&#8217;est à dire partout où vous êtes allé).</li>
</ul>
<h3>Deux usages de « reset » courant</h3>
<p>On utilisera souvent pour deux opérations très courantes.</p>
<p>La première, c&#8217;est annuler tous les ajouts dans dans l&#8217;index. Par exemple, on s&#8217;aperçoit qu&#8217;on a fait « git add . » et que plein de choses sont prêtes à être sauvegardées par erreur. Il suffit de faire :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset HEAD</pre></div></div>

<p>En effet, on se déplace jusqu&#8217;à HEAD (mais on y est déjà puisque HEAD c&#8217;est le commit actuel, donc ça ne change rien), et on met tout le contenu du dernier changeset dans l&#8217;index. Donc l&#8217;index est remis à zéro.</p>
<p>La seconde utilisation est de remettre à plat sa copie de travail. Par exemple on a fait des tas de modifications inutiles sur les fichiers et on veut recommencer à zéro avec les fichiers propres du dernier commit :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset HEAD <span style="color: #660033;">--hard</span></pre></div></div>

<p>En effet, on se déplace jusqu&#8217;à HEAD (mais on y est déjà puisque HEAD c&#8217;est le commit actuel, donc ça ne change rien), et on met tout le contenu du dernier changeset dans l&#8217;index, puis met à jour la copie de travail pour qu&#8217;elle ressemble exactement à son état lors du dernier commit.</p>
<h3>« git reset » sur des fichiers</h3>
<p>« reset » peut aussi s&#8217;appliquer directement à des fichiers, mais dans ce cas on ne peut faire ni « &#8211;hard » ni « &#8211;soft ». La seule chose que cela produit est la mise à jour de l&#8217;index. On l&#8217;utilise surtout pour annuler une modification de l&#8217;index, par exemple, supposons que je supprime TODO.txt :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">rm</span> TODO.txt
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
no changes added to commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">&quot;git add&quot;</span> and<span style="color: #000000; font-weight: bold;">/</span>or <span style="color: #ff0000;">&quot;git commit -a&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>La suppression de mon fichier est notée comme &#8220;détectée ma pas à sauvegarder&#8221;. Je dis à Git que je veux qu&#8217;il enregistre cette surpression.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git <span style="color: #c20cb9; font-weight: bold;">rm</span> TODO.txt
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #ff0000;">'TODO.txt'</span>
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Maintenant, si je fais un commit, cette suppression est enregistrée. Mais si je change d&#8217;avis ? « reset » me permet de récupérer le TODO.txt qui est dans HEAD pour le mettre dans l&#8217;index.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset <span style="color: #660033;">--</span> TODO.txt
Unstaged changes after reset:
M	TODO.txt
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
no changes added to commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">&quot;git add&quot;</span> and<span style="color: #000000; font-weight: bold;">/</span>or <span style="color: #ff0000;">&quot;git commit -a&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Et voilà, la supression ne sera pas enregistrée si je fais un commit. </p>
<p>Mais vous devez vous demander, qu&#8217;est-ce que signifie « &#8212; ». Ceci n&#8217;a rien à voir avec Git, c&#8217;est un marqueur utilisé dans n&#8217;importe quelle ligne de commande pour dire qu&#8217;il n&#8217;y a plus d&#8217;option après lui. Il n&#8217;est pas utile d&#8217;entrer dans les détails, tout ce que vous avez besoin de savoir c&#8217;est qu&#8217;il faut le mettre juste avant le nom du fichier que l&#8217;on veut remettre à zéro dans l&#8217;index.</p>
<p>Enfin, pour les besoins de l&#8217;exercice, nous alons faire un hard reset pour mettre notre copie de travail au propre :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset –hard HEAD</pre></div></div>

<p>Et voilà, retour à la case départ <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>« git checkout »</h3>
<p>La commande « checkout » toute seule ressemble beaucoup à un « reset &#8211;hard » : elle permet de se déplacer dans l&#8217;historique à un point donné et l&#8217;index ainsi que la copie de travail sont mis à jour :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span>
divers  proto.txt  test.txt  test.txt~  TODO.txt  TODO.txt~
$ git log
<span style="color: #7a0874; font-weight: bold;">&#91;</span>...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire
&nbsp;
$ git checkout bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Note: moving to <span style="color: #ff0000;">'bbfc3cf5ef3f93c4aab17b39193907a047b5617b'</span> <span style="color: #c20cb9; font-weight: bold;">which</span> isn<span style="color: #ff0000;">'t a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b &lt;new_branch_name&gt;
HEAD is now at bbfc3cf... Ceci est un commentaire
$ git log
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Sat Mar 27 18:34:49 2010 +0000
&nbsp;
    Ceci est un commentaire
&nbsp;
$ ls
divers  README.txt  test.txt~  TODO.txt  TODO.txt~  tuto.txt</span></pre></div></div>

<p>Vous voyez ici la copie de travail telle qu&#8217;elle était à notre premier commit. Vous voyez de plus text.txt~ car il est dans le .gitignore et n&#8217;a donc pas été touché. Attention cependant :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># Not currently on any branch.</span>
<span style="color: #666666; font-style: italic;"># Untracked files:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	TODO.txt~</span>
<span style="color: #666666; font-style: italic;">#	test.txt~</span></pre></div></div>

<p>Le .gitignore n&#8217;avait pas été créé à cette époque, du coup à ce niveau de l&#8217;historique, Git voit ces fichiers <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Revenons à la case départ grâce au reflog :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reflog
bbfc3cf HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: checkout: moving from master to bbfc3cf5ef3f93c4aab17b39193907a047b5617b
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
e3bfc5d HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: e3bfc5d3457756d695bbed735ea018559d8b00cd: updating HEAD
a9c07b1 HEAD<span style="color: #000000; font-weight: bold;">@</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">5</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>: a9c07b1: updating HEAD
<span style="color: #7a0874; font-weight: bold;">&#91;</span>…<span style="color: #7a0874; font-weight: bold;">&#93;</span>
$ git checkout a9c07b1
Previous HEAD position was bbfc3cf... Ceci est un commentaire
HEAD is now at a9c07b1... Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
$ ls
divers  proto.txt  test.txt  test.txt~  TODO.txt  TODO.txt~</span></pre></div></div>

<p>Jusqu&#8217;ici, pas très utile, on savait déjà faire ça avec « reset ». </p>
<p>Il y a pourtant une différence primordiale : contrairement à « reset », « checkout » <strong>ne déplace pas la branche courante</strong>, ce qui fait que si vous vous déplacez dans un endroit sans branche, vous travaillez en dehors de toute branche ! Un problème important, que nous verrons dans un autre article.</p>
<p>De plus, « checkout » permet de faire quelque chose que « reset » ne fait pas : récupérer un fichier de l&#8217;historique et l&#8217;importer dans la copie de travail. Pour cela, il suffit de lui passer en paramètre le nom du fichier.</p>
<p>Supposons qu&#8217;on veuille récupérer TODO.txt tel qu&#8217;il était 2 commits avant :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit a9c07b154a6d2e3b2435fa51bbc3a920fb1652b2
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Mon Mar <span style="color: #000000;">29</span> <span style="color: #000000;">16</span>:<span style="color: #000000;">55</span>:<span style="color: #000000;">10</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Je savais bien que j<span style="color: #ff0000;">'avais oublié quelque chose
&nbsp;
commit 1a0633ce778044aadea23eb39cdc21fc6c949989
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Sat Mar 27 21:08:04 2010 +0000
&nbsp;
    On sauvegarde l'</span>index dans l<span style="color: #ff0000;">'historique
&nbsp;
commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Sat Mar 27 19:19:33 2010 +0000
&nbsp;
    Finalement le TODO est bien comme ça
&nbsp;
commit 9f2f748ecb853a1cb616b6d387f7169dac32f243
Author: ksamuel &lt;mail@e-vidence.net&gt;
Date:   Sat Mar 27 19:12:18 2010 +0000
&nbsp;
    Ajout d'</span>un fichier et suppression d<span style="color: #ff0000;">'un autre
[…]
$ git checkout 9f2f748ecb853a1cb616b6d387f7169dac32f243 TODO.txt</span></pre></div></div>

<p>Et voilà TODO.txt revenu à son état d&#8217;origine :<br />
<code><br />
- Devenir un expert en Python.<br />
- Créer mon premier site avec Django.<br />
- Penser "ergonomie" dès le départ pour mon prochain dév.</code></p>
<p>La copie de travail et l&#8217;index sont mis à jour, du coup, la modification est prêt à être sauvegardée :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># Not currently on any branch.</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Retour à l&#8217;état départ :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset <span style="color: #660033;">--hard</span> HEAD</pre></div></div>

<p>En résumé :</p>
<ul>
<li>« git checkout hash » permet de se placer dans un endroit dans l&#8217;historique, mais ne déplace pas la branche courante. On préfère souvent utiliser « reset » pour ce genre de chose, sauf si on sait très bien ce qu&#8217;on fait.</li>
<li>« git checkout hash nom_de_fichier » permet de récupérer un fichier issu d&#8217;un changeset et de le mettre dans l&#8217;index et la copie de travail courante. Très très utile !</li>
</ul>
<p>Il est aussi possible de récupérer un fichier issu de l&#8217;index en effectuant :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git checkout <span style="color: #660033;">--</span> nom_de_fichier</pre></div></div>

<p>En pratique, on l&#8217;utilise rarement.</p>
<p><strong>Finis !</strong></p>
<p>La prochaine fois nous verrons plus en détails le principe des tags, des branches et finalement de comment fusionner des modifications entre elles avec « merge ».</p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=443</wfw:commentRss>
		</item>
		<item>
		<title>Introduction à Git pour les gens normaux</title>
		<link>http://www.e-vidence.net/?p=430</link>
		<comments>http://www.e-vidence.net/?p=430#comments</comments>
		<pubDate>Sat, 27 Mar 2010 23:10:39 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Développement]]></category>

		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=430</guid>
		<description><![CDATA[Vous êtes convaincus : git c'est génial. Mais vous n'arrivez toujours pas comprendre ce que veulent dire les incantations runiques du genre :

<pre lang="bash">git reset --mixed HEAD~1</pre>

Tout le monde sur les fora vous disent que c'est pourtant évident, et vous vous sentez très bête. Don't Panic ! Avec l'espoir de prévenir une nouvelle dépendance à l'aspirine chez les développeurs agiles, on va se faire quelques tutos e-vidents.]]></description>
			<content:encoded><![CDATA[<p>Vous êtes convaincus : <a href="http://fr.wikipedia.org/wiki/Git">Git</a> c&#8217;est génial. Tous vos collègues vous en parlent, <a href="http://github.com/">github</a> est en lien partout, Google et Linus l&#8217;utilisent et il n&#8217;y a pas un blog qui n&#8217;en disent pas du bien (à part ceux des fans de Baazar bien sûr).  Bref, vous vous sentez dans la peau des utilisateurs de CVS quand SVN est arrivé, vous voulez goûter au progrès et ne plus être has been.</p>
<p>Mais voilà, après avoir découvert qu&#8217;il n&#8217;y a presque pas de ressources en français sur l&#8217;outil, vous avez lu <a href="http://progit.org/">Pro Git</a>, vous avez posé des questions sur <a href="http://stackoverflow.com/questions/tagged/git">StackOverflow</a> et vous n&#8217;arrivez toujours pas comprendre ce que veulent dire les incantations runiques du genre :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git reset <span style="color: #660033;">--mixed</span> HEAD~<span style="color: #000000;">1</span></pre></div></div>

<p>Tout le monde sur les fora vous disent que c&#8217;est pourtant évident, et vous vous sentez très bête. Non ? Bon, c&#8217;est juste moi alors.</p>
<p>Don&#8217;t panic ! Avec l&#8217;espoir de prévenir une nouvelle dépendance à l&#8217;aspirine chez les développeurs agiles, on va se faire quelques tutos e-vidents.</p>
<h3>Pas de présentation de l&#8217;outil</h3>
<p>Je pars du principe que vous savez utiliser un système de gestion des sources. Ce n&#8217;est pas un cours de gestion de projet, mais une aide de prise en main d&#8217;un outil. Et je ne vous ferai pas la pub de Git non plus, si vous êtes là, c&#8217;est que vous êtes a priori intéressés (et en plus je trouve Mercurial plus simple, mais bon, c&#8217;est moins classe sur le CV).</p>
<p>Pour suivre ce tuto vous avez donc besoin :</p>
<ul>
<li>
D&#8217;avoir utilisé précédemment un outil de gestion de sources quelconque (SourceSafe ne compte pas).  J&#8217;inclurai des références à SVN, donc bonus pour ses utilisateurs.</li>
<li>D&#8217;être capable d&#8217;oublier tout ce que vous avez appris avec cet outil de gestion de sources. Parce qu&#8217;il va y avoir pas mal de remise en cause.</li>
<li>Savoir vous servir de la ligne de commande. Dépendants de Tortoise, allez voir chez Hg si j&#8217;y suis. Je sais ça craint, mais si vous cherchez sur Wikipedia <a href="http://fr.wikipedia.org/wiki/Linus_Torvalds">qui a codé Git</a>, ça ne vous étonnera pas.</li>
<li>Avoir<a href="http://alx.github.com/gitbook/2_installer_git.html"> installé Git</a> et être capable d&#8217;afficher sans erreur « git help ». L&#8217;installation n&#8217;a rien à voir avec notre sujet qui est de démystifier cet outil chamanique, pas de savoir comment le placer sur l&#8217;autel.</li>
</ul>
<p>Dans ce premier tuto vous allez apprendre à :</p>
<ul>
<li>Créer un dépôt local.</li>
<li>Enregistrer des modifications.</li>
<li>Voir l&#8217;effet de ces modifications.</li>
<li>Comprendre ce que fait exactement Git quand vous faites tout ça.</li>
</ul>
<p>Temps de lecture : <strong>1H30 minimum</strong>.</p>
<h3>Créer un dépôt Git</h3>
<p>Pour commencer,  le plus simple est que nous travaillons tous avec les mêmes fichiers. Voici un petit Zip qui contient des fichiers texte, un dossier et une image pour nous permettre de faire nos tests :</p>
<p><a href="http://www.2shared.com/file/12321263/82f0f73b/tuto_git_e-vidence.html">tuto_git_evidence.zip</a></p>
<p>Téléchargez l&#8217;archive, faite une extraction et, depuis un shell, mettez vous dans le dossier ainsi obtenu. Si vous faites « ls » ou « dir », vous devriez maintenant voir :</p>
<pre lang=" bash">tuto_git_e-vidence $ ls
divers  README.txt  README.txt~  TODO.txt  TODO.txt~  tuto.txt  tuto.txt~</pre>
<p>Pour créer un dépôt local, ou « repository », nous allons utiliser « git init » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git init
Initialized empty Git repository <span style="color: #000000; font-weight: bold;">in</span> ..<span style="color: #000000; font-weight: bold;">/</span>tuto_git_e-vidence<span style="color: #000000; font-weight: bold;">/</span>.git<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Pour le moment, rien de compliqué. Techniquement, il semble qu&#8217;il ne s&#8217;est rien passé à part une petite phrase pour vous dire que Git a fait son boulot. Pourtant, si vous affichez les fichiers cachés, vous verrez qu&#8217;un nouveau dossier « .git » est apparu :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-a</span>
.   divers  README.txt   TODO.txt   tuto.txt
..  .git    README.txt~  TODO.txt~  tuto.txt~</pre></div></div>

<p>« .git » est le dossier qui contient tout l&#8217;historique de votre dépôt ainsi que tous ses fichiers de configuration. En gros, sauvegarder votre dépôt est aussi simple que de sauver ce dossier. Supprimer votre dépôt, c&#8217;est juste mettre ce dossier à la poubelle.</p>
<p>Inutile de passer du temps sur « .git ». Cachez le pour ne plus y penser.</p>
<p>Ah si, une dernière chose pour les anciens de SVN. « .git » n&#8217;existe que dans le dossier racine, à l&#8217;inverse des dossiers « .svn » qui se trouvaient dans chaque sous dossier. Cela rend la dissociation entre vos fichiers normaux et ceux stockés dans Git beaucoup plus simple.</p>
<p>A ce stade là, Git n&#8217;a absolument aucune trace d&#8217;aucun fichier. « git init » ne fait que créer le dépôt, il n&#8217;ajoute rien dedans. D&#8217;une manière générale, et c&#8217;est très important car constant avec Git, Git ne fera rien sans que vous lui demandiez explicitement. Cela semble souvent rébarbatif au début, mais cela vous donne un contrôle très fin sur ce que vous faites et paie sur le long terme.</p>
<h3>Ajouter des fichiers au dépôt</h3>
<p>Git possède un fonctionnement très particulier : il sauvegarde des listes de changements. Il ne se souvient pas de comment était les fichiers à un instant T, mais il se souvient de l&#8217;ensemble des modifications faites depuis le début.</p>
<p>C&#8217;est très déroutant au départ, surtout si l&#8217;on vient de SVN, car on raisonne en termes de versions de fichiers. Avec Git, il n&#8217;y a pas de versions de fichier. Il y a juste des groupes de changements à vos fichiers de départ. On appelle cela des « changesets ».</p>
<p>Au départ, dans votre historique, il n&#8217;y a rien. Pour Git, le premier « snapshot » (l&#8217;image du système de fichier qu&#8217;il garde en interne) est une feuille blanche. On dit alors à Git de prendre en compte des fichiers, et Git ne rajoute pas les fichiers mais « l&#8217;action d&#8217;avoir créé un fichier et son contenu ».</p>
<p>En pratique, voilà comment on ajoute nos fichiers :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add README.txt         <span style="color: #666666; font-style: italic;">#1</span>
$ git add TODO.txt
$ git add tuto.txt
$ git add divers                                           <span style="color: #666666; font-style: italic;">#2</span>
$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Ceci est un commentaire&quot;</span>     <span style="color: #666666; font-style: italic;">#3</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master <span style="color: #7a0874; font-weight: bold;">&#40;</span>root-commit<span style="color: #7a0874; font-weight: bold;">&#41;</span> bbfc3cf<span style="color: #7a0874; font-weight: bold;">&#93;</span> Ceci est un commentaire
 <span style="color: #000000;">4</span> files changed, <span style="color: #000000;">5</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">0</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
 create mode <span style="color: #000000;">100755</span> README.txt
 create mode <span style="color: #000000;">100755</span> TODO.txt
 create mode <span style="color: #000000;">100644</span> divers<span style="color: #000000; font-weight: bold;">/</span>django.png
 create mode <span style="color: #000000;">100644</span> divers<span style="color: #000000; font-weight: bold;">/</span>truc_que_je_ne_classerai_jamais.txt
 create mode <span style="color: #000000;">100755</span> tuto.txt</pre></div></div>

<p>Il y a beaucoup de choses à expliquer ici.</p>
<p>#1 : D&#8217;abord, on utilise « git add » pour signaler à Git que l&#8217;on veut ajouter cette modification au dépôt. J&#8217;ai bien dit « cette modification », pas « ce fichier », bien qu&#8217;on utilise le nom du fichier pour s&#8217;y référer. Ici on dit « ajoute la modification qui consiste à la création du fichier README.txt ».</p>
<p>#2 : On fait la même chose avec  « TODO.txt » et « tuto.txt ». « git add » fonctionne de manière récursive, ce qui signifie que si vous lui donnez un dossier, Git va chercher toutes les modifications qu&#8217;il pourra trouver dans ce dossier, et ses sous-dossiers, ainsi que les sous-dossiers des sous-dossiers et ainsi de suite. Là, il s&#8217;aperçoit qu&#8217;il y a création de deux fichiers dans le sous dossier et il les ajoute.</p>
<p>#3 : Ensuite, on utilise « git commit » pour dire « sauvegarder ces modifications dans l&#8217;historique de Git ». Il est obligatoire d&#8217;écrire un commentaire à chaque commit, et on peut le faire entre autres en utilisant l&#8217;option « -m » suivie du commentaire entre guillemets.</p>
<p>Vous noterez d&#8217;une part que « git commit » est différent de celui utilisé par SVN. Commit sauvegarde les modifications dans le dépôt localement, pas du tout sur un serveur distant. Nous verrons comment sauvegarder les modifications sur un serveur distant plus tard.</p>
<p>Ensuite, du fait de l&#8217;aspect récursif de « git add », nous aurions pu faire « git add . » (&#8221;git add point&#8221;) à la racine pour ajouter toutes les modifications du dossier courant et donc de tout le projet, plutôt que de faire « git add nom_du_fichier » pour chaque fichier.</p>
<p>Certes, mais cela aurait eu un effet indésirable : celui d&#8217;ajouter également les fichiers temporaires « TODO.txt~ » et « README.txt~ ». C&#8217;est une des raisons pour laquelle la finesse de Git est agréable, vous pouvez contrôler exactement ce qui rentre et ce qui sort.</p>
<p>Tout de même, dans la plupart des cas, il est pratique de faire rapidement un « git add . ». Heureusement, Git fournit un moyen de déclarer une liste de fichiers que l&#8217;on ne souhaite jamais ajouter au dépôt : le fichier « .gitignore » (attention au point au début du nom).</p>
<p>« .gitignore » se place à la racine du dépôt, à côté du dossier « .git » (et non dedans). Il s&#8217;agit d&#8217;un fichier texte ordinaire mais caché, et sur chaque ligne vous pouvez mettre un nom de fichier que vous ne voulez jamais sauvegarder dans le dépôt. On peut utiliser l&#8217;étoile (*) comme joker.</p>
<p>Créez ce fichier (il n&#8217;existe pas par défaut), et ajoutez « *~ » sur la première ligne pour éviter la sauvegarde de tous ces fichiers temporaires.</p>
<p>Maintenant vous pouvez faire un « git add . » sans arrières pensées.</p>
<p>Comme « .gitignore » est un fichier ordinaire, il peut être ajouté au dépôt. Ce n&#8217;est pas obligatoire mais chaudement recommandé si vous souhaitez partager cette liste avec les autres développeur.</p>
<p>Donc :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add .
$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Ajout du .gitignore&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master e3bfc5d<span style="color: #7a0874; font-weight: bold;">&#93;</span> Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
 <span style="color: #000000;">1</span> files changed, <span style="color: #000000;">1</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">0</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
 create mode <span style="color: #000000;">100644</span> .gitignore</pre></div></div>

<h3>Jouons un peut avec les modifications</h3>
<p>Modifions maintenant les fichiers. Supprimons le fichier « README.txt » (qui lit encore la doc de nos jours de toute façon ?), et ajoutons une ligne dans le « TODO.txt » qui devient :</p>
<p><code>- Maîtriser Git.<br />
- Devenir un expert en Python.<br />
- Créer mon premier site avec Django.<br />
- Penser "ergonomie" dès le départ pour mon prochain dév.</code></p>
<p>On peut voir les modifications faites depuis le dernier commit grâce à la commande « git status » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
no changes added to commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">&quot;git add&quot;</span> and<span style="color: #000000; font-weight: bold;">/</span>or <span style="color: #ff0000;">&quot;git commit -a&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Les utilisateur de SVN noterons que même si on utilise pas « git rm », Git comprend tout de même que le fichier a été supprimé.</p>
<p>Ajoutons un fichier « test.txt » (créez le normalement) :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Untracked files:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	test.txt</span>
no changes added to commit <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">&quot;git add&quot;</span> and<span style="color: #000000; font-weight: bold;">/</span>or <span style="color: #ff0000;">&quot;git commit -a&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Deux grandes colonnes sont apparues. « Changed but not updated » correspond aux modifications effectuées sur des fichiers qui sont déjà pris en compte par Git. « Untracked files » liste les fichiers dont Git n&#8217;a encore jamais sauvegardé aucune modification.</p>
<p>Comme « git add » n&#8217;ajoute pas des fichiers, mais des modifications, on peut utiliser cette commande à la fois pour dire à Git de prendre en compte la création de « test.txt », mais aussi nos derniers changements :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add .
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	new file:   test.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>« Changes to be committed » contient maintenant la liste des changements qui seront sauvegardés si vous faites un commit. Si vous ne faites pas de commit, vous pouvez dire à Git de ne pas sauvegarder ces changement toute de suite.</p>
<p>Par exemple, vous ne voulez pas sauvegarde les changements faits sur « TODO.txt » immédiatement, dans ce cas vous pouvez faire « git reset » (nous verrons « reset » en détails dans un autre tuto) :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset HEAD TODO.txt
Unstaged changes after reset:
M	README.txt
M	TODO.txt</pre></div></div>

<p>« TODO.txt » passent de la colonne « Changes to be committed » à «  Changed but not updated » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	new file:   test.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Cette colonne contient tout ce que vous avez modifié mais que vous ne voulez pas encore sauvegarder. C&#8217;est exacte, vous pouvez très bien faire un commit qui ne sauvegarde que certaines modifications.</p>
<p>Vous noterez de plus que notre suppression de « README.txt » est bien détectée, mais pas ajoutée automatiquement pas le « git add » à la liste des choses à sauvegarder. C&#8217;est une protection pour vous éviter de bourrinement valider une suppression. Il faut la confirmer avec « git rm ». Contrairement à SVN, Git vous laisse utiliser « git rm » <em>a posteriori</em> sans tiquer :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git <span style="color: #c20cb9; font-weight: bold;">rm</span> README.txt
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #ff0000;">'README.txt'</span>
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    README.txt</span>
<span style="color: #666666; font-style: italic;">#	new file:   test.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Nous pouvons maintenant joyeusement sauvegarder nos modifications :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Ajout d'un fichier et suppression d'un autre&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master 9f2f748<span style="color: #7a0874; font-weight: bold;">&#93;</span> Ajout d<span style="color: #ff0000;">'un fichier et suppression d'</span>un autre
 <span style="color: #000000;">1</span> files changed, <span style="color: #000000;">0</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">1</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
 delete mode <span style="color: #000000;">100755</span> README.txt
 create mode <span style="color: #000000;">100644</span> test.txt</pre></div></div>

<p>Le modification de « TODO.txt » n&#8217;a pas été sauvegardée par Git :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Vous pouvez voir l&#8217;historique des commits en utilisant la commande « git log » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit 9f2f748ecb853a1cb616b6d387f7169dac32f243
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">12</span>:<span style="color: #000000;">18</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout d<span style="color: #ff0000;">'un fichier et suppression d'</span>un autre
&nbsp;
commit e3bfc5d3457756d695bbed735ea018559d8b00cd
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span> mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">52</span>:<span style="color: #000000;">12</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
&nbsp;
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span> mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire</pre></div></div>

<p>Le log permet de voir rapidement le nombre de commit, la date, et l&#8217;auteur des modifications. C&#8217;est un aperçu de l&#8217;historique de Git. On voit ici toute la valeur des commentaires qui permettent de comprendre rapidement de quoi il est question.</p>
<p>Il est possible de change son nom, son email, et aussi la manière dont s&#8217;affiche le log, mais ce sera pour plus tard.</p>
<p>Pour les utilisateur de GNU/Linux, sachez que vous avez la commande « tig » qui vous permet de naviguer très facilement dans le log. Sous Ubuntu, installer « tig » est un simple « apt-get ».</p>
<p>Finalement, ajoutons les modifications faites à « TODO.txt » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add TODO.txt
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Finalement le TODO est bien comme ça&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master edfb9d2<span style="color: #7a0874; font-weight: bold;">&#93;</span> Finalement le TODO est bien comme ça
 <span style="color: #000000;">1</span> files changed, <span style="color: #000000;">1</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">0</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ git log
commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">19</span>:<span style="color: #000000;">33</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Finalement le TODO est bien comme ça
&nbsp;
commit 9f2f748ecb853a1cb616b6d387f7169dac32f243
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">12</span>:<span style="color: #000000;">18</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout d<span style="color: #ff0000;">'un fichier et suppression d'</span>un autre
&nbsp;
commit e3bfc5d3457756d695bbed735ea018559d8b00cd
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">52</span>:<span style="color: #000000;">12</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
&nbsp;
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire</pre></div></div>

<p>Dense n&#8217;est-ce pas ? C&#8217;est sans doute le plus gros défaut de Git : la masse d&#8217;informations qu&#8217;il vous demande de gérer en plus au début. Une fois qu&#8217;on maîtrise le concept, ce n&#8217;est plus un problème car ces informations font partie de votre work flow, mais au début c&#8217;est un poids en plus, et il faudra patienter un peu avec que cela devienne naturel.</p>
<p>Encore une fois par rapport à SVN vous noterez les différences suivantes :</p>
<ul>
<li>
Git vous oblige à une étape intermédiaire entre vos modifications et la sauvegarde : vous devez sélectionner explicitement ce que vous voulez sauvegarder. Le bon côté, c&#8217;est que vous pouvez facilement sauvegarder des modifications et pas d&#8217;autres. Le côté ennuyeux, c&#8217;est que c&#8217;est une étape qu&#8217;on ne peut pas sauter.</li>
<li>Git vous permet de supprimer les fichiers sans paniquer.</li>
<li>Le commit de Git sauvegarde les modifications en local, pas sur un serveur distant. Vous pouvez le faire au milieu du désert si vous le souhaitez.</li>
</ul>
<h3>Comprendre ce qui vient de se passer</h3>
<p>Vous avez fait 4 commit, et il y a donc maintenant 4 « changesets » dans l&#8217;historique de votre dépôt. </p>
<p>Vous pouvez voir ces changesets avec « git log », le plus récent étant le premier affiché. :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">19</span>:<span style="color: #000000;">33</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Finalement le TODO est bien comme ça
&nbsp;
commit 9f2f748ecb853a1cb616b6d387f7169dac32f243
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">12</span>:<span style="color: #000000;">18</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout d<span style="color: #ff0000;">'un fichier et suppression d'</span>un autre
&nbsp;
commit e3bfc5d3457756d695bbed735ea018559d8b00cd
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">52</span>:<span style="color: #000000;">12</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ajout <span style="color: #c20cb9; font-weight: bold;">du</span> .gitignore
&nbsp;
commit bbfc3cf5ef3f93c4aab17b39193907a047b5617b
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">34</span>:<span style="color: #000000;">49</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Ceci est un commentaire</pre></div></div>

<p>Vous noterez la ligne « commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231 ». Le code étrange à côté du mot « commit » est &#8220;le nom&#8221; du changeset, son identifiant unique, aussi appelé « hash ». Si vous voulez vous référer à un changeset en particulier, notez ce hasg (il est différent pour vous et moi car nous n&#8217;avons pas le même dépôt).</p>
<p>Vous pouvez voir quelle est la différence entre un changeset et un autre avec « git diff », et cette commande attend le hash d&#8217;un autre changeset. Par exemple, pour voir quel sont les différences entre ce qu&#8217;il y a maintenant dans notre projet et ce qu&#8217;il y avait dans le commit « Ajout d&#8217;un fichier et suppression d&#8217;un autre » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git <span style="color: #c20cb9; font-weight: bold;">diff</span>  9f2f748ecb853a1cb616b6d387f7169dac32f243
<span style="color: #c20cb9; font-weight: bold;">diff</span> <span style="color: #660033;">--git</span> a<span style="color: #000000; font-weight: bold;">/</span>TODO.txt b<span style="color: #000000; font-weight: bold;">/</span>TODO.txt
index 664dc6b..a85daaf <span style="color: #000000;">100755</span>
<span style="color: #660033;">---</span> a<span style="color: #000000; font-weight: bold;">/</span>TODO.txt
+++ b<span style="color: #000000; font-weight: bold;">/</span>TODO.txt
<span style="color: #000000; font-weight: bold;">@@</span> -<span style="color: #000000;">1</span>,<span style="color: #000000;">3</span> +<span style="color: #000000;">1</span>,<span style="color: #000000;">4</span> <span style="color: #000000; font-weight: bold;">@@</span>
+- Maîtriser Git.
 - Devenir un expert en Python.
 - Créer mon premier site avec Django.
 - Penser <span style="color: #ff0000;">&quot;ergonomie&quot;</span> dès le départ pour mon prochain dév.</pre></div></div>

<p>Pour déchiffrer ce message, il faut le couper en deux :</p>
<p><code>diff --git a/TODO.txt b/TODO.txt<br />
index 664dc6b..a85daaf 100755<br />
--- a/TODO.txt<br />
+++ b/TODO.txt<br />
@@ -1,3 +1,4 @@</code></p>
<p>Indique de quoi on va parler. Ici, il que l&#8217;on va voir les modification apportées à « TODO.txt ». Ensuite :</p>
<p><code>+- Maîtriser Git.<br />
 - Devenir un expert en Python.<br />
 - Créer mon premier site avec Django.<br />
 - Penser "ergonomie" dès le départ pour mon prochain dév.</code></p>
<p>Est le contenu du fichier lui-même, annoté pour montrer où se situent les ajouts (+) et les retraits (-). Ici c&#8217;est un peut confus car mes lignes commences déjà par « - » <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> Il existe par ailleurs des moyens plus confortables de voir les différences et les status, mais ce n&#8217;est pas l&#8217;objet du jour.</p>
<p>Ok, on voit ce qui s&#8217;est passé dans notre projet, mais comment Git voit-il tout cela ? Réponse en schémas :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git_history.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git_history.png" alt="" title="git_history" width="442" height="403" class="aligncenter size-full wp-image-433" /></a></p>
<p>Comme vous le voyez, chaque changeset n&#8217;est pas indépendant, mais pointe vers un autre et le sens de la flèche est contre intuitif.</p>
<p>On pourrait penser que la flèche pointe vers le changeset suivant, en fait, pas du tout : chaque changeset pointe vers son « parent », c&#8217;est à dire le changeset précédent. En effet, il applique des modifications sur son parent.</p>
<p>On peut donc lire le diagramme ci-dessus comme : </p>
<p>« Finalement le TODO est bien comme ça » est une série de modification sur « Ajout d&#8217;un fichier et suppression d&#8217;un autre » qui est une série de modifications sur « Ajout du .gitignore » qui est une série de modifications sur « Ceci est un commentaire ».</p>
<p>Git conserve un historique de modifications, et l&#8217;unité est un groupe de modifications. Utiliser Git, ce n&#8217;est rien d&#8217;autre dire où l&#8217;on se trouve dans l&#8217;historique. En clair, contrairement à SVN, on ne dit pas «j&#8217;ai tels fichiers à ma disposition maintenant » mais, « je me trouve à tel changeset dans l&#8217;historique ».</p>
<p>Cela signifie qu&#8217;il y a dans Git, en permanence, un pointeur pour dire où vous êtes. L&#8217;historique ne bouge pas, c&#8217;est vous qui bougez !</p>
<p>Ce pointeur, Git l&#8217;appelle « HEAD », et ce n&#8217;est ni plus ni moins qu&#8217;un qu&#8217;un gros panneau qui vous dit « vous êtes ici » : </p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git_head.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git_head.png" alt="" title="git_head" width="500" height="281" class="aligncenter size-full wp-image-434" /></a></p>
<p>« HEAD » ne contient rien. « HEAD » est juste un marqueur pour vous indiquez votre position dans l&#8217;historique. Quand plus tard vous apprendrez à revenir en arrière, l&#8217;historique ne bougera pas, c&#8217;est vous qui bougerez :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git_moved_head.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git_moved_head.png" alt="" title="git_moved_head" width="499" height="293" class="aligncenter size-full wp-image-435" /></a></p>
<h3>Ne pas confondre Index, HEAD et la copie de travail</h3>
<p>Les schémas que vous venez de voir sont incomplets, car Git possède une grande subtilité qu&#8217;il faut absolument comprendre pour pouvoir l&#8217;utiliser : vous ne travaillez jamais sur « HEAD ».</p>
<p>« HEAD » est le marqueur qui vous indique où vous vous trouvez dans l&#8217;historique, il serait donc normal de penser que c&#8217;est là où l&#8217;on travail. Pas du tout.</p>
<p>« HEAD » pointe sur le dernier changeset, qui est une copie immuable et <strong>on ne peut pas la modifier</strong>. </p>
<p>Mais alors, dans quoi travaille-t-on ?</p>
<p>Et bien Git ajoute deux notions supplémentaires :</p>
<ul>
<li>la copie de travail;</li>
<li>l&#8217;index.</li>
</ul>
<p>La copie de travail, c&#8217;est votre projet tel que vous pouvez le voir. Ce sont les fichiers que vous modifiez, supprimez, ajoutez. Ces fichiers ne sont pas sauvegardés dans Git. Ce sont des fichiers normaux, et si vous faites une modifications sur un fichier puis que vous le supprimez avant de faire un commit, les modifications seront perdues.</p>
<p><strong>En clair, vous travaillez toujours en dehors de Git.</strong></p>
<p>Git ne vous permet pas de travailler dans son historique, il vous permet juste :</p>
<ul>
<li>d&#8217;ajouter des modifications;</li>
<li>de récupérer des modifications;</li>
<li>de vous déplacer dans les modifications.</li>
</ul>
<p>Un changeset ne se modifie pas (en tout cas, pas comme vous le pensez), et on à jamais accès directement à « HEAD ». « HEAD » pointe sur un changeset, qui est une boîte, un coffre fort qui contient et protège les dernières modifications enregistrées.</p>
<p>Mais alors pourquoi mettre un panneau « vous êtes ici » si vous n&#8217;êtes pas vraiment ici ? Et bien vous êtes ici au sens Git du terme, c&#8217;est à dire que <strong>c&#8217;est ici, sur ce changeset, que se rajoutera votre prochain commit.</strong></p>
<p>Nous avons donc deux choses importantes :</p>
<ul>
<li>L&#8217;historique : une liste de changesets dans laquelle on peut se promener mais qu&#8217;on ne peut pas modifier. On peut juste lui rajouter un nouveau changeset.</li>
<li>La copie de travail : votre projet, des fichiers normaux, modifiables, et complètement en dehors de Git.</li>
</ul>
<p>Mais alors, à quoi sert l&#8217;index ?</p>
<p>Il s&#8217;agit tout simplement de l&#8217;étape qui vous permet de faire passer vos modifications hors de Git, dans Git.</p>
<h3>L&#8217;index, ce changeset mal connu</h3>
<p>Concentrez vous bien sur cette partie parce que c&#8217;est la notion qu&#8217;il manque à la plupart des utilisateurs de Git en péril. Si vous comprenez ça, la suite sera facile.</p>
<p>L&#8217;index est un changeset, au même titre que tous les autres, mais il a deux particularités :</p>
<ul>
<li>Il est modifiable par les commandes « add », « rm » et « reset »;</li>
<li>Il n&#8217;est pas inclus dans l&#8217;historique Git.</li>
</ul>
<p>L&#8217;index est juste une étape intermédiaire qui vous permet de dire, « voilà à quoi doit ressembler mon prochain changeset dans l&#8217;historique si je fais un commit ». C&#8217;est un outil qu&#8217;on peut modifier à loisir, remettre à zéro, casser, reconstruire, démolir, etc.</p>
<p>Voici donc un schéma plus complet du fonctionnement de Git :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git_index.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git_index.png" alt="" title="git_index" width="500" height="362" class="aligncenter size-full wp-image-441" /></a></p>
<p>A chaque commit, l&#8217;index est sauvegardé par dessus le changeset sur lequel pointe « HEAD », puis « HEAD » est déplacé sur le nouveau changeset :</p>
<p><a href="http://www.e-vidence.net/wp-content/uploads/2010/03/git_commit.png"><img src="http://www.e-vidence.net/wp-content/uploads/2010/03/git_commit.png" alt="" title="git_commit" width="500" height="336" class="aligncenter size-full wp-image-438" /></a></p>
<h3>Un peu de pratique</h3>
<p>Modifiez TODO.TXT pour qu&#8217;il ressemble à ceci :</p>
<p><code>- Maîtriser Git.<br />
- Mettre un commentaire sur ce tuto parce qu'il est pas mal quand même.<br />
- Devenir un expert en Python.<br />
- Créer mon premier site avec Django.<br />
- Penser "ergonomie" dès le départ pour mon prochain dév.</code></p>
<p>Supprimez aussi le fichier « tuto.txt ».</p>
<p>Vous allez voir « git status » d&#8217;un nouvel oeil :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	deleted:    tuto.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>« Changed but not updated » veut dire « changé dans la copie de travail mais pas dans l&#8217;index ». En gros, vous avez modifié des fichiers, mais vous n&#8217;avez pas ajouté ces modifications dans l&#8217;index. Ce que l&#8217;on fait avec « git add/rm » :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git add TODO.txt
$ git <span style="color: #c20cb9; font-weight: bold;">rm</span>  tuto.txt
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #ff0000;">'tuto.txt'</span>
$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#	deleted:    tuto.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>«  Changes to be committed » veut dire, « ces modification sont dans l&#8217;index, elles seront sauvegardées au prochain commit ». On peut choisir qu&#8217;une de ces modifications ne soit pas appliquée :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git reset HEAD TODO.txt
Unstaged changes after reset:
M	TODO.txt</pre></div></div>

<p>« git reset » remplace la modification de « TODO.txt » de l&#8217;index par l&#8217;état de « TODO.txt » qui se trouvait dans « HEAD ».</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git status
<span style="color: #666666; font-style: italic;"># On branch master</span>
<span style="color: #666666; font-style: italic;"># Changes to be committed:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	deleted:    tuto.txt</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># Changed but not updated:</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)</span>
<span style="color: #666666; font-style: italic;">#   (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;">#	modified:   TODO.txt</span>
<span style="color: #666666; font-style: italic;">#</span></pre></div></div>

<p>Pour l&#8217;instant, rien n&#8217;est sauvegardé :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">19</span>:<span style="color: #000000;">33</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Finalement le TODO est bien comme ça
<span style="color: #7a0874; font-weight: bold;">&#91;</span>…<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>On commit :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;On sauvegarde l'index dans l'historique&quot;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>master 1a0633c<span style="color: #7a0874; font-weight: bold;">&#93;</span> On sauvegarde l<span style="color: #ff0000;">'index dans l'</span>historique
 <span style="color: #000000;">1</span> files changed, <span style="color: #000000;">0</span> insertions<span style="color: #7a0874; font-weight: bold;">&#40;</span>+<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #000000;">1</span> deletions<span style="color: #7a0874; font-weight: bold;">&#40;</span>-<span style="color: #7a0874; font-weight: bold;">&#41;</span>
 delete mode <span style="color: #000000;">100755</span> tuto.txt</pre></div></div>

<p>Les modifications de l&#8217;index sont maintenant dans l&#8217;historique et « HEAD » pointe dessus :</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ git log
commit 1a0633ce778044aadea23eb39cdc21fc6c949989
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">21</span>:08:04 <span style="color: #000000;">2010</span> +0000
&nbsp;
    On sauvegarde l<span style="color: #ff0000;">'index dans l'</span>historique
&nbsp;
commit edfb9d255b7a77b7babeaeda3ea6630b38ca1231
Author: ksamuel <span style="color: #000000; font-weight: bold;">&lt;</span>mail<span style="color: #000000; font-weight: bold;">@</span>e-vidence.net<span style="color: #000000; font-weight: bold;">&gt;</span>
Date:   Sat Mar <span style="color: #000000;">27</span> <span style="color: #000000;">19</span>:<span style="color: #000000;">19</span>:<span style="color: #000000;">33</span> <span style="color: #000000;">2010</span> +0000
&nbsp;
    Finalement le TODO est bien comme ça
<span style="color: #7a0874; font-weight: bold;">&#91;</span>…<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<h3>Git est complexe mais pas compliqué</h3>
<p>Si vous avez bien suivi le tuto, vous devriez maintenant comprendre, non seulement le principe de modifier / sauvegarder, mais aussi ce que fait Git derrière quand vous lui demandez de telles actions.</p>
<p>Ce n&#8217;est pas difficile à comprendre, mais c&#8217;est beaucoup d&#8217;informations à retenir comme en témoigne ce long tuto. Malgré cela, les explications que l&#8217;on trouve sur le net sont généralement très incomplètes ou nébuleuses, et j&#8217;espère donc que cet article vous aura réconcilié avec ce merveilleux outil qu&#8217;est Git.</p>
<p>Dans le prochain tuto, nous verrons <a href="http://www.e-vidence.net/?p=443">comment revenir en arrière avec Git</a> quand on a fait des modifications qui ne nous plaisent pas à l&#8217;aide des commande « checkout » et « reset ».</p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=430</wfw:commentRss>
		</item>
		<item>
		<title>Nom d&#8217;un crotal, pourquoi &#8220;self&#8221; en Python ?</title>
		<link>http://www.e-vidence.net/?p=379</link>
		<comments>http://www.e-vidence.net/?p=379#comments</comments>
		<pubDate>Sat, 20 Mar 2010 19:31:54 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[self]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=379</guid>
		<description><![CDATA[Python utilise « self » et non « this » pour designer la référence à l'objet courant, et de plus il vous oblige à le déclarer en paramètre des méthodes ! Lisez la suite si vous savez utiliser « self » mais que vous voudriez comprendre pourquoi ça marche.]]></description>
			<content:encoded><![CDATA[<p>Python utilise « self » et non « this » pour designer la référence à l&#8217;objet courant, et de plus il vous oblige à le déclarer en paramètre des méthodes ! Lisez la suite si vous savez utiliser « self » mais que vous voudriez comprendre pourquoi ça marche.</p>
<h3>« self » est une variable ordinaire</h3>
<p>« self » n&#8217;est pas un mot réservé en Python. C&#8217;est une variable ordinaire. Elle n&#8217;a rien de spéciale. Rien. De fait elle n&#8217;existe pas par défaut, et si vous essayez de l&#8217;afficher sans l&#8217;avoir déclaré vous aurez une erreur:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">NameError</span>: name <span style="color: #483d8b;">'self'</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> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>toto<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">NameError</span>: name <span style="color: #483d8b;">'toto'</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined</pre></div></div>

<p>Vous noterez que l&#8217;erreur n&#8217;est pas « Used &#8217;self&#8217; outside of a class » ou autre. C&#8217;est une banale erreur de déclaration. Et vous pouvez très bien mettre n&#8217;importe quoi dans « self »:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">self</span> = <span style="color: #483d8b;">&quot;e-vidence.net&quot;</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: #008000;">self</span><span style="color: black;">&#41;</span>
e-vidence.<span style="color: black;">net</span></pre></div></div>

<p>En fait, l&#8217;usage de « self » est purement une convention. En Python vous écrivez :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<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;">self</span>.<span style="color: black;">eggs</span>
…
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Mais ce n&#8217;est pas du tout une obligation. Vous pouvez utiliser n&#8217;importe quel nom de variable en lieu et place de « self ». Vous préférez « this » :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span>this<span style="color: black;">&#41;</span>:
...        <span style="color: #ff7700;font-weight:bold;">return</span> this.<span style="color: black;">eggs</span>
…
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Ça marche très bien. Vous vous sentez d&#8217;humeur taquine, voir carrément mégalo?</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span>MOOOOI<span style="color: black;">&#41;</span>:
...        <span style="color: #ff7700;font-weight:bold;">return</span> MOOOOI.<span style="color: black;">eggs</span>
…
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Ça marche également. La raison à cela est très simple :<strong> Python se fiche complètement de « self »</strong>. « self » n&#8217;est pas du tout le centre du problème, Python ne fonctionne pas comme les autres langages, en attribuant à une variable locale la référence à l&#8217;instance courante.</p>
<p>Pourtant, tout le monde utilise « self », et ce <strong>par pure convention</strong>. En effet, si tous les codeurs utilisent la même notation, on sait de quoi on parle. Ainsi, n&#8217;utilisez jamais autre chose que « self », tout ce que vous gagneriez serait un surplus de complexité. La plupart des outils de coloration syntaxique pour Python supposent que « self » est l&#8217;instance en cours.</p>
<p>Si c&#8217;est un choix collectif, pourquoi avoir choisi « self » et non « this », qui semble plus commun ? La raison est simple, Python s&#8217;inspire du langage Smalltalk-80, qui utilise aussi « self ». C++ est sorti la même année, en 1980, et utilisait « this ». Il n&#8217;y avait donc pas de choix « le plus populaire » à l&#8217;époque et on utilisait les conventions de son modèle. Ainsi, Java et PHP s&#8217;inspirant du C++, utilisent « this ».</p>
<p>Il y a une grosse différence cependant : Java et PHP attribuent automatiquement cette valeur à « this ». Pyhon se fiche complètement de « self », qui n&#8217;est qu&#8217;une conséquence d&#8217;un mécanisme plus important : le passage automatique d&#8217;une référence à l&#8217;instance en cours à toutes les méthodes de cette instance.</p>
<h3>Comment « self » arrive dans votre méthode</h3>
<p>« Self » est une variable ordinaire, et la raison pour laquelle on ne peut y accéder que dans une méthode et donc la même que pour toute variable : vous ne la déclarez que dans les méthodes, et donc son scope est limité au bloc dans lequel vous la déclarez.</p>
<p>Vous seul déclarez « self ». Vous êtes la seule raison pour laquelle « self » est là. Et vous pouvez très bien ne pas déclarer self :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>selfless<span style="color: black;">&#41;</span>:
...        <span style="color: #ff7700;font-weight:bold;">return</span> selfless<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">eggs</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Ce que vous ne pouvez pas faire en revanche, c&#8217;est déclarer une méthode sans aucun paramètre :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<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;">3</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">TypeError</span>: pondre<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> takes no arguments <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> given<span style="color: black;">&#41;</span></pre></div></div>

<p>Vous notez que l&#8217;erreur n&#8217;est pas « self is missing » mais quelque chose de plus simple, plus générique. Vous avez déclaré une méthode et cela marche parfaitement. C&#8217;est à l&#8217;utilisation que ça plante, on vous dit que votre méthode n&#8217;attend aucun argument, mais que pourtant on lui en a passé un. C&#8217;est une erreur très courante, qui n&#8217;a rien à voir avec la programmation orientée objet :</p>

<div class="wp_syntax"><div 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> dis_bonjour<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;bonjour&quot;</span><span style="color: black;">&#41;</span>
...     
<span style="color: #66cc66;">&gt;&gt;&gt;</span> dis_bonjour<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
bonjour
<span style="color: #66cc66;">&gt;&gt;&gt;</span> dis_bonjour<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;argument_bidon&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">TypeError</span>: dis_bonjour<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> takes no arguments <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> given<span style="color: black;">&#41;</span></pre></div></div>

<p>Nous touchons ici le coeur du problème : Python ne créé pas automatiquement une variable qui contient une référence à l&#8217;instance en cours, il passe automatiquement l&#8217;instance en cours comme premier paramètre de toutes les méthodes de cette instance. A votre charge de récupérer cette référence dans la variable de votre choix.</p>
<p>C&#8217;est pour cela que l&#8217;on doit mettre « self » comme premier paramètre des toutes les méthodes : pour récupérer la référence que Python passe automatiquement. « Self » n&#8217;a rien de spécial, c&#8217;est un paramètre normal que vous créez, ce qui est spécial c&#8217;est que Python passe automatiquement au moins un paramètre à toutes les méthodes, même si on ne lui demande rien.</p>
<p><strong>C&#8217;est une décision architecturale</strong>, une des philosophies de Python est « explicit is better than implicit », c&#8217;est à dire qu&#8217;il vaut mieux dire clairement ce qu&#8217;on veut plutôt que compter sur un sous-entendu. Quand vous êtes en Java, vous pouvez ne pas mettre « this », et dans la plupart des cas cela marchera car il est sous-entendu. En Python on ne peut pas : on doit dire ceci est l&#8217;instance, je la prend là, je la met là, et là je change son attribut.</p>
<p>Vous allez me dire, « ok, mais on aurait pu rendre explicite cette manipulation sans obliger à déclarer la variable ». C&#8217;est vrai après tout, cela aurait été plus automatique, et Python n&#8217;est-il pas là pour vous aider à économiser du temps en automatisant ce qui peut l&#8217;être ? C&#8217;est un point valide, et je ne suis pas Guido pour trouver une réponse pertinente, mais je peux vous présenter les côtés intéressants de cette fonctionnalité. Car s&#8217;en est une.</p>
<h3>Jouons un peu avec et sans « self »</h3>
<p>Python passe automatiquement l&#8217;instance de l&#8217;objet en cours si vous utilisez cette méthode depuis un objet.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<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;">self</span>.<span style="color: black;">eggs</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># 'o' est un objet de type  Ornithorynque, python passe donc 'self' à 'pondre'</span></pre></div></div>

<p>Mais on peut aussi passer cette instance manuellement ! Il suffit d&#8217;appeler la méthode à partir de la classe, et non d&#8217;un objet :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> orni = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> orni.<span style="color: black;">eggs</span> = <span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> Ornithorynque.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span>orni<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Python ne passe pas de référence car on appel « pondre » depuis la classe</span>
<span style="color: #ff4500;">2</span></pre></div></div>

<p>Ici on créé notre propre référence, et on la passe. C&#8217;est cette référence qui sera utilisée par la méthode « pondre », puisque c&#8217;est le premier paramètre, et que le premier paramètre est « self ».</p>
<p>Python est un langage qui vous laissent aller très loin dans l&#8217;introspection. Cette fonctionnalité en fait partie, et on peut lui trouver des usages très tordus. Imaginez par exemple qu&#8217;on peut récupérer des instances par paramétrages dynamique, et inclure ou non l&#8217;instance en cours :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span><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> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>orni.<span style="color: black;">eggs</span> <span style="color: #ff7700;font-weight:bold;">for</span> orni <span style="color: #ff7700;font-weight:bold;">in</span> args<span style="color: black;">&#41;</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">eggs</span> = <span style="color: #ff4500;">23</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span>Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># l'instance en cours est dans le lot</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">23</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> Ornithorynque.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span>Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Une application concrète ? Ok, je n&#8217;en ai aucune, mais c&#8217;est super marrant non ?</p>
<p>Python est un langage très souple, il vous encourage largement au duck typing et rien ne vous empêche de prendre des morceaux de code qui n&#8217;ont rien à voir et d&#8217;en faire un tout cohérent :</p>

<div class="wp_syntax"><div 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> voler<span style="color: black;">&#40;</span>animal<span style="color: black;">&#41;</span> :
…    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'%s voooooooole'</span> <span style="color: #66cc66;">%</span> animal
...</pre></div></div>

<p>Cette fonction, merci à Python, peut accepter des paramètres très variés :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>voler<span style="color: black;">&#40;</span>Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>__main__.<span style="color: black;">Ornithorynque</span> <span style="color: #008000;">object</span> at 0xb74cc7ac<span style="color: #66cc66;">&gt;</span> voooooooole
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>voler<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Je'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Je voooooooole
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</span>
...
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span><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> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>orni.<span style="color: black;">eggs</span> <span style="color: #ff7700;font-weight:bold;">for</span> orni <span style="color: #ff7700;font-weight:bold;">in</span> args<span style="color: black;">&#41;</span>
...
…   <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__str__</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;">'Orni'</span>
…
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>voler<span style="color: black;">&#40;</span>Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Orni voooooooole</pre></div></div>

<p>On peut très bien vous avoir donné cette fonction, par exemple dans une bibliothèque généraliste sur la lévitation qui ne connait rien aux ornithorynques. Tout développeur agile avec un peu d&#8217;expérience vous dira que c&#8217;est très crédible comme scenario <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Maintenant, vous voulez écrire une méthode similaire pour votre cher mammifère ovipare. C&#8217;est inutile, hop, un petit cout de colle et vous rajoutez à ce bec de canard et cette queue de castor des ailes de cygne :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> Ornithorynque.<span style="color: black;">voler</span> = voler
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o = Ornithorynque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> o.<span style="color: black;">voler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'Orni voooooooole'</span></pre></div></div>

<p>La fonction « voler » accepte un argument qui doit être une instance de quelque chose. Si vous attachez cette fonction à la classe &#8216;Ornithorynque&#8217;, appeler « o.voler » implique que Python passe automatiquement l&#8217;instance en cours à cette fonction comme premier paramètre. Donc ça marche tout seul.</p>
<p>Notez que contrairement à Javascript, ça ne marche pas sur les built-ins :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">int</span>.<span style="color: black;">voler</span> = voler
&nbsp;
<span style="color: #008000;">TypeError</span>: can<span style="color: #483d8b;">'t set attributes of built-in/extension type '</span><span style="color: #008000;">int</span><span style="color: #483d8b;">'</span></pre></div></div>

<p>Ce qui est bien dommage car j&#8217;entrevois des applications titanesques dans le transport aérien si les &#8216;integers&#8217; pouvaient voler à côté des &#8216;platipus&#8217;. Mais passons.</p>
<p>Sachez que Python est un langage qui s&#8217;étale en profondeur plus qu&#8217;en largeur. A chaque fois, c&#8217;est simple au début, mais si vous creusez vous verrez qu&#8217;il y a de nombreuses possibilités dont vous n&#8217;aviez même pas idée. </p>
<p>Aviez vous déjà pensé que tout est objet. Donc les fonctions sont des objets. Les classes sont des objets. Et qu&#8217;il peuvent être passés à la place de l&#8217;instance en cours&#8230; </p>
<p>Ça ouvre des perspectives non ? </p>
<p>D&#8217;ailleurs Python lui-même utilise déjà des petites astuces de ce genre. Par exemple il n&#8217;existe pas de méthodes statiques. Mais si vous voulez quelque chose similaire, vous pouvez utiliser le décorateur « classmethod ». En fait, cette méthode statique n&#8217;est qu&#8217;une méthode normale à laquelle on passe une référence à la classe en cours plutôt qu&#8217;une instance de l&#8217;objet en cours.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Ornithorynque<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
...
...    <span style="color: black;">eggs</span> = <span style="color: #ff4500;">3</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: black;">&#41;</span>:
…      <span style="color: #008000;">self</span>.<span style="color: black;">eggs</span> = <span style="color: #ff4500;">4</span>
…
…   @<span style="color: #008000;">classmethod</span>
...    <span style="color: #ff7700;font-weight:bold;">def</span> pondre<span style="color: black;">&#40;</span>cls<span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># la convention ici passe de 'self' à 'cls' pour éviter la confusion</span>
...        <span style="color: #ff7700;font-weight:bold;">return</span> cls.<span style="color: black;">eggs</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>Ornithorynque.<span style="color: black;">pondre</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Malheureusement, même Python pose des limites et on ne peut pas définir de « self » par default. « self » n&#8217;est pas en cause, c&#8217;est une variable ordinaire. Mais Python surveille le premier paramètre d&#8217;une méthode pour voir si il correspond au même type que l&#8217;objet qu&#8217;il doit traiter :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> SuperFile<span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</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: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># un peut de magie ici pour hériter de file</span>
…         <span style="color: #008000;">file</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><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;">def</span> super_write<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>=<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>, txt=<span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># un 'self' par default qui écrit sur stdout</span>
…         <span style="color: #008000;">self</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>txt.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
…         
<span style="color: #66cc66;">&gt;&gt;&gt;</span> sf = SuperFile<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;woooot.txt&quot;</span>, <span style="color: #483d8b;">&quot;w&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> SuperFile.<span style="color: black;">super_write</span><span style="color: black;">&#40;</span>txt=<span style="color: #483d8b;">&quot;J'aime les pythons et les ornitorynques&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #008000;">TypeError</span>: unbound method super_write<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> must be called <span style="color: #ff7700;font-weight:bold;">with</span> SuperFile instance <span style="color: #ff7700;font-weight:bold;">as</span> first argument <span style="color: black;">&#40;</span>got nothing instead<span style="color: black;">&#41;</span></pre></div></div>

<p>Dommage&#8230; Mais peut être que je suis tordu ?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=379</wfw:commentRss>
		</item>
		<item>
		<title>[Résolu - par Python] Aidez-moi, je ne comprends rien aux encodages !</title>
		<link>http://www.e-vidence.net/?p=416</link>
		<comments>http://www.e-vidence.net/?p=416#comments</comments>
		<pubDate>Sun, 07 Mar 2010 23:18:43 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[ascii]]></category>

		<category><![CDATA[encodage]]></category>

		<category><![CDATA[encoding]]></category>

		<category><![CDATA[utf-8]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=416</guid>
		<description><![CDATA[Les pages Web qui affichent des « � », les emails qui titrent « RÃ©union Ã reporter » et vos scripts Python qui geignent « SyntaxError: Non-ASCII character », c'est une histoire d'encodage. L'encodage est un sujet éminemment complexe, mais ce que vous avez besoin de savoir pour développer l'esprit tranquille est on ne peu plus simple.]]></description>
			<content:encoded><![CDATA[<p>Les pages Web qui affichent des «&nbsp;�&nbsp;», les emails qui titrent «&nbsp;RÃ©union Ã reporter&nbsp;» et vos scripts Python qui geignent «&nbsp;SyntaxError: Non-ASCII character&nbsp;», c&#8217;est une histoire d&#8217;encodage. L&#8217;encodage est un sujet éminemment complexe, mais ce que vous avez besoin de savoir pour développer l&#8217;esprit tranquille est on ne peut plus simple. D&#8217;autres l&#8217;ont fait avant moi (<a href="http://french.joelonsoftware.com/Articles/Unicode.html">joel</a>, <a href="http://genezys.net/blog/post/99-comprendre-les-jeux-de-caracteres">vincent</a>, <a href="http://sebsauvage.net/python/charsets_et_encoding.html">seb</a>), mais c&#8217;est le genre de vaccin qui nécessite un rappel.</p>
<h3>Question de représentation</h3>
<p>Prenons un animal au hasard. L&#8217;hirondelle d&#8217;Afrique par exemple. Ou d&#8217;Europe. A vide en tout cas. Bon ça devient trop compliqué, prenons un chien.</p>
<p>Le mot «&nbsp;chien&nbsp;», représente l&#8217;animal quadrupède et cabochard que nous apprécions tous (ou pas). «&nbsp;Chien&nbsp;», est une représentation de l&#8217;animal, pas l&#8217;animal lui-même. Encore heureux, un chien n&#8217;est pas une série de caractères alignés, c&#8217;est un organisme complet avec poils, bave et toutes ces joyeusetés. Mais pour nous permettre de communiquer entre nous, de garder trace aussi en écrivant sur papier et informatiquement, nous utilisons le mot «&nbsp;chien&nbsp;».</p>
<p>«&nbsp;Chien&nbsp;» est une représentation, et il en existe d&#8217;autres. Les anglais utilisent «&nbsp;dog&nbsp;», les espagnols utilisent «&nbsp;perro&nbsp;». On parle du même truc qui aboie et mange trop de croquettes, mais on utilise une représentation différente, composée de symboles textuels : les mots.</p>
<p>Un autre exemple souvent cité, celui des chiffres. On utilise «&nbsp;5&nbsp;» pour représenter le concept de cinq, mais les romains utilisaient «&nbsp;V&nbsp;». On parle de la même chose, la donnée est la valeur de cinq, mais sa représentation peut être «&nbsp;5&nbsp;», «&nbsp;V&nbsp;», «&nbsp;cinq&nbsp;», «&nbsp;five&nbsp;», «&nbsp;cinco&nbsp;», etc.</p>
<p>C&#8217;est un concept très important en informatique :<strong> la représentation est différente de la donnée</strong>. Par exemple quand vous faites :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> age = <span style="color: #ff4500;">5</span></pre></div></div>

<p>Python ne stocke pas 5, car l&#8217;ordinateur ne connait que des zéros et des uns. Il stocke quelque chose qui ressemble à sa représentation binaire : «&nbsp;101&nbsp;». On parle de la même chose, le concept du «&nbsp;nombre 5&nbsp;», mais Python et votre esprit le représentez différemment.</p>
<p>Et bien pour le chaîne de caractère, c&#8217;est pareil. Si vous faites :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">nom = <span style="color: #483d8b;">'e-vidence'</span></pre></div></div>

<p>Python ne stocke par la chaîne &#8216;e-vidence&#8217; mais sa représentation. Chaque lettre est traduite en un nombre, qui lui, est gardé en mémoire.</p>
<p>Là où ça se gâte, c&#8217;est pour savoir : <strong>à quel nombre correspond quelle lettre</strong> ?</p>
<p>Et ça, ça dépend de l&#8217;encodage utilisé. L&#8217;encodage, c&#8217;est un énorme tableau qui dit à quelle lettre correspond quel nombre. Il y a <a href="http://docs.python.org/library/codecs.html">beaucoup d&#8217;encodages différents</a>. <a href="http://java.sun.com/j2se/1.4.2/docs/guide/intl/encoding.doc.html">Beaucoup, beaucou</a>p. La plupart ne permettent pas de représenter toutes les lettres, car il existent des caractères spéciaux dans toutes les langues : chinois, suédois, russe&#8230;</p>
<p>Votre système d&#8217;exploitation (Windows, Mac, Linux, etc) lit et écrit en utilisant un encodage. Python également. Toute donnée texte est écrite en utilisant un encodage, et on ne peut lire ce texte que si on connait son encodage d&#8217;origine.</p>
<p>En gros, si pendant des années vous avez manipulé des textes avec Python sans connaître leur encodage d&#8217;origine, c&#8217;est parce que vous avez eu de la chance. Si, si, c&#8217;est un coup de moule, promis.</p>
<h3>Les encodages, du plus simple au plus complexe</h3>
<p>Le plus simple des encodage est l&#8217;encodage <a href="http://fr.wikipedia.org/wiki/Ascii">ASCII</a>. Inventé par les américains, il contient 128 caractères, dont une centaine sont visibles :</p>

<div class="wp_syntax"><div 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;">string</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: #dc143c;">string</span>.<span style="color: black;">printable</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!&quot;#$%&amp;<span style="color: #000099; font-weight: bold;">\'</span>()*+,-./:;&lt;=&gt;?@[<span style="color: #000099; font-weight: bold;">\\</span>]^_`{|}~ <span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\x</span>0b<span style="color: #000099; font-weight: bold;">\x</span>0c'</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: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">printable</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">100</span></pre></div></div>

<p>Ces caractères vous sont familiers ? En Europe, on les retrouve partout, et c&#8217;est une des raisons pour laquelle on ignore souvent les problèmes d&#8217;encodage : ASCII suffit à de très nombreux usages dans nos pays. En fait, tant que vous n&#8217;utilisez pas «&nbsp;é&nbsp;» ou «ç&nbsp;» et autres exotismes, tout ira bien car ASCII est souvent contenu dans la plupart des autres encodages.</p>
<p>Seulement viendra le moment où vous devrez traiter un texte français correctement écris. Viendra le moment où vous traiterez un texte espagnol, et tous ces vilains «&nbsp;~&nbsp;», et, en bidouillant, vous vous en sortirez. Et un matin, vous codez un projet open source avec un coréen et vous êtes forcés de chercher à comprendre.</p>
<p>D&#8217;abord, il faut savoir que chaque langue ou presque à son tableau de correspondant «&nbsp;lettre - nombre&nbsp;». Le plus utilisé en Europe est l&#8217;encodage «&nbsp;ISO-8859-1&nbsp;», qui permet de traduire en nombre tous les caractères ASCII, mais aussi les accents, les cédilles, les tildes et tout le toutim. Windows utilise un encodage quasiment similaire appelé «&nbsp;CP-1252&nbsp;». </p>
<p>Mais que se passe-t-il si vous recevez un texte en chinois, encodé par exemple avec «&nbsp;GB2312&nbsp;» ? Et bien vous recevez des nombres qui correspondent à des caractères chinois. Si le programme sait que le texte est chinois et qu&#8217;il a accès à un encodage chinois, il pourra traduire chaque chiffre en caractère.</p>
<p>Dans le cas contraire, le programme essayera de transformer les chiffres en utilisant votre encodage, souvent ISO-8859, ce qui vous donnera soit des lettres incohérentes, soit un gros plantage car il y a bien plus de caractères en chinois que de lettres en français et certains nombres n&#8217;apparaissent donc pas dans ISO-8859.</p>
<p>Pour pouvoir lire un texte, quel qu&#8217;il soit (page Web, email, fichier texte, XML, nom de fichier, titre de MP3, etc), il faut savoir dans quel encodage il est écrit et avoir cet encodage sous la main. Si ça marche sans cela, c&#8217;est simplement que par chance le texte est écrit dans l&#8217;encodage par défaut de votre système.</p>
<p>De plus, pas besoin de chercher un exemple tordu à base de correspondances asiatiques pour avoir des problèmes d&#8217;encodage. Un simple lecteur de musique peut afficher «&nbsp;Les chants de Noël&nbsp;» avec une orthographe des plus farfelus, simplement parce que la personne qui a enregistré la chanson la fait depuis un autre système.</p>
<p>Vu le nombre de langues et de caractères spéciaux, il a été créé un encodage qui permet de traduire tous les caractères : «&nbsp;unicode&nbsp;». Unicode possède des sous ensembles tel que UTF-8 et UTF-16, et   nous allons essentiellement utiliser UTF-8 dans cet article car c&#8217;est le plus rependu.</p>
<p>Unicode résout donc en théorie la plupart des problèmes, mais en pratique des milliers d&#8217;applications utilisent encore des encodages locaux. Il va falloir faire avec.</p>
<h3>Gérer tout ce boxon avec Python</h3>
<p>Pour Python, il nous faut nous soucier de trois couches : l&#8217;encodage du système d&#8217;exploitation, l&#8217;encodage du fichier du script Python et l&#8217;encodage de Python. Pour se simplifier les choses, mettez tout en unicode.</p>
<p>Écrivez votre script Python en UTF-8, et pour cela, réglez votre éditeur de texte sur UTF-8 dans ses préférences. Rajoutez ensuite la ligne suivant en première ligne de tous vos script :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding= UTF-8 -*-</span></pre></div></div>

<p>Cela précise à Python que c&#8217;est écrit en UTF-8. Sans cette mention, la moindre apparition d&#8217;un «&nbsp;é&nbsp;» déclenchera l&#8217;erreur «&nbsp;SyntaxError: Non-ASCII character&nbsp;». ASCII est en effet l&#8217;encodage par défaut de Python.</p>
<p>Enfin, écrivez vos chaînes en les préfixant de &#8216;u&#8217; :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> comment = u<span style="color: #483d8b;">'De façon évidente'</span></pre></div></div>

<p>Ce &#8216;u&#8217; force ce Python à créer une chaîne encodée en UTF-8.</p>
<p>Maintenant, tout ce que vous avez à l&#8217;intérieur de votre programme est en UTF-8, vous ne pouvez plus avoir de problèmes d&#8217;encodage sans entrée ou sortie de données. Mais un programme qui reste fermé sur lui-même est rarement très utile, il va donc falloir apprendre à traduire depuis et vers UTF-8.</p>
<p>Quand vous lisez un fichiez, vous faites ainsi :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fichier.txt&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> ligne <span style="color: #ff7700;font-weight:bold;">in</span> fichier :
… <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>ligne<span style="color: black;">&#41;</span>
…</pre></div></div>

<p>Lire un fichier est une entrée de données. Si le fichier est écrit dans votre encodage, vous n&#8217;aurez pas de problème. Typiquement, si vous êtes sous Windows et que vous lisez un fichier écrit par Windows, il sera en ASCII ou ISO-8859, et tout ira bien. Mais si vous recevez un fichier issu d&#8217;un Mac, il sera probablement en UTF-8, et alors votre programme affichera des caractères étranges ou plantera.</p>
<p>Le meilleur moyen de prévenir cela est de décoder la donnée ainsi lue. Python fournit aux chaîne les méthodes «&nbsp;encode&nbsp;» et «&nbsp;decode&nbsp;», qui convertissent les données depuis et vers UTF-8 :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fichier.txt&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> ligne <span style="color: #ff7700;font-weight:bold;">in</span> fichier :
… ligne_decodee = ligne.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;UTF-8&quot;</span><span style="color: black;">&#41;</span>
… <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>ligne_decodee<span style="color: black;">&#41;</span></pre></div></div>

<p>Là vous allez me dire, «&nbsp;mais pourquoi on décode un fichier en UTF-8 vers de l&#8217;UTF-8 ?&nbsp;». Tout simplement parce que Python ne sait pas que le fichier est en UTF-8. Il n&#8217;a aucun moyen de le savoir. Et comme son encodage par défaut n&#8217;est pas UTF-8, il va enregistrer ces chaines en mémoires dans son encodage par défaut au lieu du bon.</p>
<p>A l&#8217;inverse, si vous êtes sous Linux, et que vous voulez lire un fichier Windows :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fichier.txt&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> ligne <span style="color: #ff7700;font-weight:bold;">in</span> fichier :
… ligne_decodee = ligne.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CP-1252&quot;</span><span style="color: black;">&#41;</span>
… <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>ligne_decodee<span style="color: black;">&#41;</span></pre></div></div>

<p><strong>Ligne_décodee sera toujours de l&#8217;UTF-8, dans l&#8217;exemple 1 comme dans l&#8217;exemple 2</strong>, donc on sait ce qu&#8217;on traite.</p>
<p>Un moyen rapide de lire un fichier encodé dans un autre encodage est d&#8217;utiliser le module codecs :</p>

<div class="wp_syntax"><div 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;">codecs</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier = <span style="color: #dc143c;">codecs</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fichier.txt&quot;</span>, <span style="color: #483d8b;">&quot;ISO-8859&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># on donne l'encodage ici</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> ligne_decodee <span style="color: #ff7700;font-weight:bold;">in</span> fichier : <span style="color: #808080; font-style: italic;"># les lignes sont automatiquement décodées !</span>
... <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>ligne_decodee<span style="color: black;">&#41;</span></pre></div></div>

<p>Pour certain d&#8217;entre vous</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>ligne_decodee<span style="color: black;">&#41;</span></pre></div></div>

<p>affiche peut être des caractères bizarres, notamment si vous êtes sous Windows. C&#8217;est normal, votre système d&#8217;exploitation affiche dans la console avec son propre encodage. Non seulement il faut décoder les données en entrée, mais il faut aussi les réencoder à la sortie !</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> fichier = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;fichier.txt&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> ligne <span style="color: #ff7700;font-weight:bold;">in</span> fichier :
… ligne_decodee = ligne.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CP-1252&quot;</span><span style="color: black;">&#41;</span>
… chaine_transformee = faire_quelque_chose_avec_les_chaines<span style="color: black;">&#40;</span>ligne_decodee<span style="color: black;">&#41;</span>
… <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>chaine_transformee.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'CP-1252'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Ici, c&#8217;est un exemple avec un fichier, mais c&#8217;est valable pour toute donnée texte. Vous lisez un nom de fichier ? Il faut faut décoder et encoder. Vous téléchargez ou générez des pages Web ? Il faut décoder et encoder. Vous faites des requêtes à une base de données ? Il faut décoder et encoder.</p>
<p><em>En résumé: si des données rentrent qui ne sont pas de l&#8217;UTF-8, vous décodez. En interne, vous faites ce que vous voulez, tout est en UTF-8. Ensuite si des données sortent, vous encodez si le destinataire attend autre chose de l&#8217;UTF-8.</em></p>
<p>Pour vous donner une idée de l&#8217;importance du phénomène, voici le chemin d&#8217;une page Web et l&#8217;influence des encodages :</p>
<ul>
<li>Génération par un script Python écrit dans un encodage et stockant en mémoire les chaînes dans un encodage.</li>
<li>Récupération de chaînes depuis la base de données qui stockent du texte dans un encodage qui peut être différent de l&#8217;encodage du texte lui-même.</li>
<li>Création du HTML dans un encodage, et spécification d&#8217;un encodage dans la balise META.<br />
Envoie de la page par un serveur qui spécifie l&#8217;encodage dans le HEADER.</li>
<li>Réception par le navigateur Web, codé dans un encodage, et réglé sur un encodage, installé sur un système qui possède son propre encodage.</li>
</ul>
<p>Votre texte est en permanence décodé et encodé. Votre boulot est que au milieu de ce processus, votre script comprenne les données qui entrent, et les renvoient soit dans l&#8217;encodage d&#8217;origine, soit avec la mention du nouvel encodage.</p>
<p>Arrivé à ce stade, vous comprenez maintenant une chose : il est impossible de gérer cela correctement si on ne sait pas quel est l&#8217;encodage d&#8217;origine des données. On ne peut pas lire un livre si on ne sait pas dans quelle langue il est écrit, on ne peut pas écouter une émission de radio si on ne sait pas dans quelle langue elle est diffusée, et on ne peut pas manipuler un texte si on ne sait pas dans quel encodage il est représenté.</p>
<h3>Comment déterminer l&#8217;encodage d&#8217;origine ?</h3>
<p>Mauvaise nouvelle, il n&#8217;y a aucun moyen sûr de le faire, et c&#8217;est pour cela que parfois encore Firefox affiche de «&nbsp;�&nbsp;», et Outlook des «&nbsp;Ã©&nbsp;». Mais on peut faire «&nbsp;au mieux&nbsp;».</p>
<p>Faire au mieux c&#8217;est :</p>
<ul>
<li>Bien connaître les encodages qu&#8217;on utilise soi-même : votre serveur, vos textes, votre base de données&#8230; Vous devez parfaitement savoir comment ils stockent le texte. Dans le meilleurs des cas en UTF-8.</li>
<li>Partir du principe que si les données extérieures communiquent un encodage, c&#8217;est le bon. Par exemple les pages Web déclarent l&#8217;encodage dans une balise meta :

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;</pre></div></div>

</li>
<li>Ne pas faire pour autant confiance à ces données extérieures pour autant et gérer les possibles erreurs de décodage :

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">try</span> :
…     u<span style="color: #483d8b;">&quot;é&quot;</span>.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;UTF-8&quot;</span><span style="color: black;">&#41;</span>
… <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">UnicodeEncodeError</span>:
…     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Ça ne peut pas marcher !'</span><span style="color: black;">&#41;</span>
…</pre></div></div>

</li>
<li>Dans le doute, on peut tenter de <a href="http://chardet.feedparser.org/">deviner l&#8217;encodage</a>. Ce n&#8217;est pas très fiable, mais c&#8217;est mieux que rien.</ul>
</li>
<p><em>En résumé, le seul moyen fiable de déterminer l&#8217;encodage d&#8217;origine est que le système à l&#8217;origine des données donne explicitement son nom. De votre côté, pour limiter les dégât, utilisez UTF-8 partout : base de données, serveur, page Web, etc.</em></p>
<h5>u&#8217;Le mot de la fin&#8217;.encode(&#8221;ISO-8869-1&#8243;)</h5>
<p>Ne devenez pas parano avec les encodages. Si vous développez un programme, mettez tout en UTF-8 et tout ira bien. Le jour où une erreur survient, ce sera à cause d&#8217;une donnée externe. Ce jour là, et ce jour là seulement, préoccupez vous de décoder et encoder ce flux de données qui entre et qui sort.</p>
<p>Sachez enfin que Python 3 gère maintenant par défaut toutes les chaînes en unicode, plus besoin de préfixer de &#8216;u&#8217;. Bien sûr, c&#8217;est loin d&#8217;être la version la plus utilisée.</p>
<p>Enfin, pour ne pas vous laisser sans un petit plus, voici un <a href="http://sebsauvage.net/python/snyppets/#stripaccents">snippet</a> que vous pouvez utiliser normaliser tous les caractères spéciaux qui ont un équivalent ASCII :</p>

<div class="wp_syntax"><div 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;">unicodedata</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> s = u<span style="color: #483d8b;">&quot;éèêàùçÇ&quot;</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: #dc143c;">unicodedata</span>.<span style="color: black;">normalize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'NFKD'</span>, s<span style="color: black;">&#41;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ascii'</span>,<span style="color: #483d8b;">'ignore'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
eeeaucC</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=416</wfw:commentRss>
		</item>
		<item>
		<title>Iterables, iterators et generators : les meilleurs amis de Python (oh, et on explique yield aussi)</title>
		<link>http://www.e-vidence.net/?p=382</link>
		<comments>http://www.e-vidence.net/?p=382#comments</comments>
		<pubDate>Tue, 23 Feb 2010 21:45:21 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[generators]]></category>

		<category><![CDATA[iterables]]></category>

		<category><![CDATA[iterators]]></category>

		<category><![CDATA[yield]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=382</guid>
		<description><![CDATA[Pourquoi y a-t-il « range() » et « xrange() » ? Que fait « (x**2 for x in (1, 2, 3)) » ? A quoi sert le mot clé « yield » ? Dois-je mettre les chocolats dans ma bouche un par un ou tous d'un coup ? La réponse, en bilingue français-Python.]]></description>
			<content:encoded><![CDATA[<p>Pourquoi y a-t-il « range() » et « xrange() » ? Que fait « (x**2 for x in (1, 2, 3)) » ? A quoi sert le mot clé « yield » ? Dois-je mettre les chocolats dans ma bouche un par un ou tous d&#8217;un coup ? La réponse, en bilingue français-Python.</p>
<h3>Iterables</h3>
<p>Quand vous créez une liste, vous pouvez récupérer chacun de ses éléments un par un. On parle d&#8217;itération :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> maliste = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> maliste :
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>i<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></div></div>

<p>Maliste est un iterable, en anglais cela signifie « que l&#8217;on peut itérer ». En Python, itérable est une caractéristique que n&#8217;importe quel objet peut avoir, il lui suffit de déclarer la méthode « __iter__() » ou «  __getitem__ » :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>maliste.<span style="color: #0000cd;">__iter__</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>method-wrapper <span style="color: #483d8b;">'__iter__'</span> of <span style="color: #008000;">list</span> <span style="color: #008000;">object</span> at 0xb73f648c<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p>Ainsi, les chaînes de caractères sont aussi des itérables :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> machaine = <span style="color: #483d8b;">&quot;e-vidence.net&quot;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>machaine.<span style="color: #0000cd;">__getitem__</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>method-wrapper <span style="color: #483d8b;">'__getitem__'</span> of <span style="color: #008000;">str</span> <span style="color: #008000;">object</span> at 0xb75005c0<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> lettre <span style="color: #ff7700;font-weight:bold;">in</span> machaine:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>lettre<span style="color: black;">&#41;</span>
e
-
v
i
d
e
n
c
e
.
<span style="color: black;">n</span>
e
t</pre></div></div>

<p>Les dicionnaires aussi sont des iterables :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> dico = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;site&quot;</span>: <span style="color: #483d8b;">&quot;e-vidence&quot;</span>, <span style="color: #483d8b;">&quot;langage&quot;</span>: <span style="color: #483d8b;">&quot;python&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>dico.<span style="color: #0000cd;">__iter__</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>method-wrapper <span style="color: #483d8b;">'__iter__'</span> of <span style="color: #008000;">dict</span> <span style="color: #008000;">object</span> at 0x8bc7acc<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> dico:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span>
...
<span style="color: black;">langage</span>
<span style="color: #dc143c;">site</span></pre></div></div>

<p>Bref, les iterables, c&#8217;est « les trucs sur lesquels on peut faire une boucle &#8220;for&#8221; ».  Les tuples, les sets et  les fichiers aussi ! Du coup quand vous utilisez « range() », vous créez une liste, donc un iterable. Et quand vous utilisez une liste en intention, vous créez une liste, donc un itérable.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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: #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: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</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><span style="color: black;">&#91;</span>x<span style="color: #66cc66;">*</span>x <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: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> ma_liste = <span style="color: black;">&#91;</span>x<span style="color: #66cc66;">*</span>x <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: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> mylist :
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">4</span></pre></div></div>

<p>Les itérables sont très pratiques car ils se comportent tous pareils : on se fiche de savoir ce qu&#8217;il y a dedans, on sait qu&#8217;on peut prendre chaque élément un par un. Vous n&#8217;avez rien à faire, vous n&#8217;avez même pas besoin de savoir si il est plein, ou si il utilise « __iter__() » ou quoique ce soit. On utilise « for », et c&#8217;est tout ce qu&#8217;on a besoin de savoir.</p>
<p>Cependant les listes, tuples et autres ont un défaut, ils stockent toutes les valeurs en mémoire. Ce n&#8217;est pas forcément ce que vous voulez si vous avez énormément de valeurs à passer en revue.</p>
<h3>Iterators</h3>
<p>Les itérateurs sont des objets qui permettent d&#8217;utiliser les iterables. Normalement vous ne les voyez jamais, car ils sont automatiquement utilisés par Python de manière invisible. Vous pouvez très bien coder en Python sans jamais avoir besoin de savoir ce qu&#8217;est un itérateur. Connaître les itérateurs relève donc plutôt de la culture générale.</p>
<p>Quand un objet déclare la méthode « __iter__() », cette méthode retourne un itérateur :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> iterateur = l.<span style="color: #0000cd;">__iter__</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>iterateur<span style="color: black;">&#41;</span></pre></div></div>

<p>On utilise généralement la function « iter() » pour éviter d&#8217;appeler directement « __iter__() » :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</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><span style="color: #008000;">iter</span><span style="color: black;">&#40;</span>l<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>A quoi ça sert donc ? Et bien un itérateur possède une méthode « next() » qui permet d&#8217;avoir l&#8217;élément suivant de l&#8217;itérable dont il est issu. Quand il n&#8217;y a plus d&#8217;élément, il lève l&#8217;exception « StopIteration » :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> iterateur = <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span>l<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>iterateur.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">1</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>iterateur.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">2</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>iterateur.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">3</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>iterateur.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">StopIteration</span></pre></div></div>

<p>Cet objet, c&#8217;est ce que « for » utilise ! Quand vous utilisez « for », Python récupère automatiquement l&#8217;itérateur et appelle « next() ». D&#8217;ailleurs, « for » fonctionne sur les itérateurs :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> iterateur = <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span>l<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterateur :
...     <span style="color: #ff7700;font-weight:bold;">print</span> x
...     
...     
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">2</span>
<span style="color: #ff4500;">3</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> iterateur :
... <span style="color: #ff7700;font-weight:bold;">print</span> x</pre></div></div>

<p>Comme vous l&#8217;avez remarqué, on ne peut utiliser un itérateur qu&#8217;une seule fois. Une fois vidé, il reste vide.</p>
<h3>Generators</h3>
<p>Les générateurs sont des itérables, mais vous pouvez les lire une seule fois. C&#8217;est parcequ&#8217;ils ne gardent pas les valeurs en mémoire, mais les génèrent à la volée :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> mon_generateur = <span style="color: black;">&#40;</span>x<span style="color: #66cc66;">*</span>x <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: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> mon_generateur :
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">4</span></pre></div></div>

<p>C&#8217;est la même chose que l&#8217;exemple du début avec la liste en intention, mais au lieu d&#8217;utiliser « [] », on utilise « () ». La grosse différence, c&#8217;est qu&#8217;on ne pourra pas faire un « for » une deuxième fois sur « mon_generateur » car les générateurs ne peuvent être lus qu&#8217;une fois : ici il calcule 0, puis oublie la valeur et calcule 1, puis calcule 4. Une valeur à la fois.<br />
L&#8217;avantage, c&#8217;est que « mon_generateur » consomme très peu de mémoire : aucune liste ne stocke toutes les valeurs.</p>
<h3>Yield</h3>
<p>« Yield » est un mot clé que l&#8217;on utilise exactement comme « return », sauf que la fonction va retourner un générateur :</p>

<div class="wp_syntax"><div 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> creerGenerateur<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
...   <span style="color: black;">maliste</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;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> maliste :
...        <span style="color: #ff7700;font-weight:bold;">yield</span> i<span style="color: #66cc66;">*</span>i
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> mon_generateur = creerGenerateur<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># créer le gérérateur</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>mygenerator<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># mon generateur est un objet !</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> mon_generateur:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
<span style="color: #ff4500;">0</span>
<span style="color: #ff4500;">1</span>
<span style="color: #ff4500;">4</span></pre></div></div>

<p>Ici, c&#8217;est un exemple inutile, mais c&#8217;est pratique si votre fonction retourne un très gros ensemble de données que l&#8217;on a besoin de lire une seule fois.</p>
<p>Pour bien comprendre « yield », il faut se rentrer dans la tête qu&#8217;<strong>à l&#8217;appel de la fonction le code de la fonction n&#8217;est pas éxécuté</strong>. C&#8217;est le piège : la function retourne un objet générateur et ne fait rien d&#8217;autre ! Ensuite, le code va s&#8217;exécuter à chaque fois que « for » utilise le générateur.</p>
<p>Maintenant la partie difficile (concentrez vous, lisez plusieurs fois) :</p>
<p>La première fois que le corps de la function va être exécuté, il va s&#8217;exécuter du début jusqu&#8217;à ce qu&#8217;il rencontre « yield », et il va retourner la première valeur de la boucle. Puis, à chaque nouvel appel, on va éxécuter la partie de la boucle une nouvelle fois, arriver à « yield », et retourner la nouvelle valeur. On va continuer ainsi jusqu&#8217;à ce qu&#8217;il n&#8217;y ai plus de valeur à retourner.</p>
<p>Un générateur est considéré comme vide une fois que la fonction s&#8217;exécute, mais ne rencontre plus « yield », quelle qu&#8217;en soit la raison : boucle vide, if / else, exception&#8230;</p>
<p>Oh, et pour les tatillons, un générateur est son propre itérateur :</p>

<div class="wp_syntax"><div 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> creerGenerateur<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
...   <span style="color: black;">maliste</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;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> maliste :
...        <span style="color: #ff7700;font-weight:bold;">yield</span> i<span style="color: #66cc66;">*</span>i
...     
<span style="color: #66cc66;">&gt;&gt;&gt;</span> g = creerGenerateur<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>g == <span style="color: #008000;">iter</span><span style="color: black;">&#40;</span>g<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> g = creerGenerateur<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>g.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">0</span></pre></div></div>

<p>C&#8217;est bon, vous savez tout ce qu&#8217;il est nécessaire pour jouer avec les itérateurs et les générateurs, ainsi donc que « yield ». Pour les anglophiles, vous pouvez allez encore plus loin avec une passionnante présentations de <a href="http://www.dabeaz.com/">Beazley</a> sur des <a href="http://www.dabeaz.com/generators/Generators.pdf">astuces à base de générateurs</a>.</p>
<p>&#8230;<br />
&#8230;<br />
Toujours là ?<br />
&#8230;<br />
&#8230;</p>
<p>Bon encore un peu pour la route alors.</p>
<p>A ce stade là, vous avez du deviner à quoi sert « xrange() » : c&#8217;est l&#8217;équivalent de « range() », mais c&#8217;est un générateur (et un peu plus, car il possède son propre type) :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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: #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: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</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><span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">xrange</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: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>type <span style="color: #483d8b;">'xrange'</span><span style="color: #66cc66;">&gt;</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: #008000;">xrange</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: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</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: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">xrange</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: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Si vous vous sentez vaillant, jetez un coup d&#8217;oeil à cet exemple amusant de générateur :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">class</span> Banque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># créons une banque, qui fabrique des distributeurs</span>
...    <span style="color: black;">crise</span> = <span style="color: #008000;">False</span>
...    <span style="color: #ff7700;font-weight:bold;">def</span> creer_distributeur<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;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">crise</span> :
...            <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #483d8b;">&quot;100 €&quot;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> bnp = Banque<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># quand tout va bien, on a autant de monnaie que l'on veut</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> distributeur_du_coin = bnp.<span style="color: black;">creer_distributeur</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>distributeur_du_coin .<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">100</span> €
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>distributeur_du_coin.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">100</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: black;">&#91;</span>distributeur_du_coin.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> cash <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: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'100 €'</span>, <span style="color: #483d8b;">'100 €'</span>, <span style="color: #483d8b;">'100 €'</span>, <span style="color: #483d8b;">'100 €'</span>, <span style="color: #483d8b;">'100 €'</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> bnp.<span style="color: black;">crise</span> = <span style="color: #008000;">True</span> <span style="color: #808080; font-style: italic;"># la crise est là, plus de monaie</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>distributeur_du_coin.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">StopIteration</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> distributeur_de_la_defense = bnp.<span style="color: black;">creer_distributeur</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># même pour les nouveaux</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>distributeur_de_la_defense.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">StopIteration</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> bnp.<span style="color: black;">crise</span> = <span style="color: #008000;">False</span> <span style="color: #808080; font-style: italic;"># si la crise s'en va, les anciens distributeurs sont vides</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>distributeur_du_coin.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">StopIteration</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> nouveau_distributeur = bnp.<span style="color: black;">creer_distributeur</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># mais les nouveaux sont pleins</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> cash <span style="color: #ff7700;font-weight:bold;">in</span> nouveau_distributeur :
...    <span style="color: #ff7700;font-weight:bold;">print</span> cash
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
<span style="color: #ff4500;">100</span> €
...</pre></div></div>

<p>Voilà qui peut être utile, par exemple pour gérer l&#8217;accès à une ressource.</p>
<p>Enfin, si vous travaillez beaucoup avec les itérateurs, faites connaissance avec le module « itertools » : dupliquer des générateurs, les chaîner, groupe des valeurs, utiliser « map() » et « zip() » sans créer une nouvelle liste&#8230; Une seule réponse  : « import itertools »</p>
<p>Un exemple ? Voyons l&#8217;ordre d&#8217;arrivée possible d&#8217;une courses de 4 chevaux :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> chevaux = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> courses = <span style="color: #dc143c;">itertools</span>.<span style="color: black;">permutations</span><span style="color: black;">&#40;</span>chevaux<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>courses<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>itertools.<span style="color: black;">permutations</span> <span style="color: #008000;">object</span> at 0x8c2a77c<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> resultat <span style="color: #ff7700;font-weight:bold;">in</span> courses:
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>resultat<span style="color: black;">&#41;</span>
...
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</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: #ff4500;">2</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">2</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: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</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: #ff4500;">1</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
 <span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Happy hacking <img src='http://www.e-vidence.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=382</wfw:commentRss>
		</item>
		<item>
		<title>Python, la tête dans les « * »</title>
		<link>http://www.e-vidence.net/?p=398</link>
		<comments>http://www.e-vidence.net/?p=398#comments</comments>
		<pubDate>Wed, 17 Feb 2010 15:08:04 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Python]]></category>

		<category><![CDATA[*]]></category>

		<category><![CDATA[étoile]]></category>

		<category><![CDATA[paramétrage dynamique]]></category>

		<category><![CDATA[unpacking]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=398</guid>
		<description><![CDATA[L'utilisation du signe étoile (*) en Python est très simple, mais certains cas sont peu intuitifs. Les nouveaux venus ont souvent besoin d'un peu plus d'explications que ce que donne la doc. Les utilisateurs d'autres langages sont généralement déroutés car ils sont habitués certaines fonctionnalités qu'on ne retrouvent pas en Python. Voici une petite carte du ciel de la constellation du serpent.]]></description>
			<content:encoded><![CDATA[<p>L&#8217;utilisation du signe étoile (*) en Python est très simple, mais certains cas sont peu intuitifs. Les nouveaux venus ont souvent besoin d&#8217;un peu plus d&#8217;explications que ce que donne la doc. Les utilisateurs d&#8217;autres langages sont généralement déroutés car ils sont habitués certaines fonctionnalités qu&#8217;on ne retrouvent pas en Python.</p>
<h3>Ce que « * » ne permet pas de faire</h3>
<p>Il n&#8217;y a pas de pointeurs en Python, et les passages par références sont automatiques. Du coup :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">mon_objet = MaClasse<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mon_pointeur = <span style="color: #66cc66;">*</span>mon_objet
ma_valeur = <span style="color: #66cc66;">**</span>mon_pointeur</pre></div></div>

<p>N&#8217;existe pas en Python. On ne peut pas récupérer un pointeur. On ne peut pas choisir si l&#8217;on passe une variable par valeur ou par référence. Tout est automatique et transparent.</p>
<h3>Les usages basiques de « * »</h3>
<p>La multiplication et la puissance fonctionnent comme on l&#8217;attend :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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: #ff4500;">2</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># multiplier 2 par 3</span>
<span style="color: #ff4500;">6</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: #ff4500;">2</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># élever 2 à la puissance 3</span>
<span style="color: #ff4500;">8</span></pre></div></div>

<p>Mais déjà, Python se démarque du lot car l&#8217;opérateur * est surchargé par défaut, et peut s&#8217;appliquer aux chaînes de caractères et aux listes. Pour les chaîne, c&#8217;est simple :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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;">&quot;a&quot;</span> <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 peut multiplier une chaîne par un nombre, et cela donne une chaîne</span>
aaa
<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;">&quot;a&quot;</span> <span style="color: #66cc66;">**</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># ça ne marche pas avec les puissances</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: #66cc66;">**</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #008000;">pow</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: <span style="color: #483d8b;">'str'</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #483d8b;">'int'</span></pre></div></div>

<p>Pour les listes, c&#8217;est plus subtile. Une liste de nombre se multiplie sans y penser :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</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>l <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
 <span style="color: #808080; font-style: italic;"># on peut multiplier une liste par un nombre, cela donne une liste</span>
<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">3</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>l <span style="color: #66cc66;">**</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
 <span style="color: #808080; font-style: italic;"># ça ne marche pas avec les puissances</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: #66cc66;">**</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #008000;">pow</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: <span style="color: #483d8b;">'list'</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #483d8b;">'int'</span></pre></div></div>

<p>En revanche, multiplier une liste d&#8217;objets modifiables ne fait que répéter la référence vers cet objet:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span>
 <span style="color: #808080; font-style: italic;"># on fait une liste contenant un dictionnaire</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> dicos = l <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">3</span>
 <span style="color: #808080; font-style: italic;"># on peut multiplier une liste par un nombre, cela donne une liste</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>dicos<span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>On a l&#8217;impression que le comportement est le même que précédemment, en fait pas du tout. Ici on a pas une liste de 3 dictionnaires, mais une liste de 3 références faire le même dictionnaire. Si on modifie le premier élément de la liste, tous sont modifiés :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> d = dicos<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># on récupère ce qu'on croit être le premier dictionnaire</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Nouvelle cle&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Nouvelle valeur&quot;</span> <span style="color: #808080; font-style: italic;"># on le modifie</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>dicos<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># afficher la liste montre que les 3 dictionnaires sont en fait un seul et même objet</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'Nouvelle cle'</span>: <span style="color: #483d8b;">'Nouvelle valeur'</span><span style="color: black;">&#125;</span>,
 <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Nouvelle cle'</span>: <span style="color: #483d8b;">'Nouvelle valeur'</span><span style="color: black;">&#125;</span>,
 <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Nouvelle cle'</span>: <span style="color: #483d8b;">'Nouvelle valeur'</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span></pre></div></div>

<h3>Unpacking</h3>
<p>Python intègre une fonctionnalité, l&#8217;unpacking, qui permet de prendre chaque élément d&#8217;une séquence et de les attribuer à des variables distinctes, d&#8217;un seul coup. C&#8217;est un raccourcis très partique :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> drapeau = <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bleu&quot;</span>, <span style="color: #483d8b;">&quot;blanc&quot;</span>, <span style="color: #483d8b;">&quot;rouge&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># ici on utilise un tuple, mais ça marche avec les listes</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> premiere_couleur = drapeau<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> deuxieme_couleur = drapeau<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> troisieme_couleur = drapeau<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>premiere_couleur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'bleu'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>deuxieme_couleur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'blanc'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>troisieme_couleur<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'rouge'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> couleur1, couleur2, couleur3 =  drapeau <span style="color: #808080; font-style: italic;"># la même opération, en une ligne grace à l'unpacking</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>couleur1<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'bleu'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>couleur2<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'blanc'</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>couleur3<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'rouge'</span></pre></div></div>

<p>Vous n&#8217;avez rien à faire, l&#8217;unpacking est automatique : il suffit de mettre à gauche du signe « = » le même nombre de variables qu&#8217;il y a d&#8217;élément dans la séquence à droite du signe « = ». Dans le cas contraire, Python râle :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> un, deux = drapeau
<span style="color: #008000;">ValueError</span>: too many values to unpack
<span style="color: #66cc66;">&gt;&gt;&gt;</span> un, deux, trois, quatre = drapeau
<span style="color: #008000;">ValueError</span>: need more than <span style="color: #ff4500;">3</span> values to unpack</pre></div></div>

<p>Quel rapport avec « * » ? Et bien il permet de forcer l&#8217;unpacking dans le cas où c&#8217;est ambigüe. Faisons une petite fonction de test qui ne fait qu&#8217;afficher chacun de ses paramètres :</p>

<div class="wp_syntax"><div 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> afficher_trois_elements<span style="color: black;">&#40;</span>elem1, elem2=<span style="color: #008000;">None</span>, elem3=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>elem1<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>elem2<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>elem3<span style="color: black;">&#41;</span>
...
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span>drapeau<span style="color: black;">&#41;</span>
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bleu'</span>, <span style="color: #483d8b;">'blanc'</span>, <span style="color: #483d8b;">'rouge'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">None</span>
<span style="color: #008000;">None</span></pre></div></div>

<p>Passer drapeau affiche logiquement le tuple comme premier paramètre, et ensuite les valeurs par défaut du premier et du second paramètre. En utilisant « * », nous pouvons forcer l&#8217;unpacking de telle sorte que les valeurs du tuple soient passées individuellement comme autant de paramètres :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>drapeau<span style="color: black;">&#41;</span>
bleu
blanc
rouge</pre></div></div>

<p>Très pratique quand vous utiliser une collection tout au long du programme pour vous éviter de sans cesse trainer des variables intermédiaires. D&#8217;autant que ça marche combiné aux slices :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> l = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">&quot;element que l'on ne veut pas&quot;</span><span style="color: black;">&#93;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>l<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: #ff4500;">1</span>
<span style="color: #ff4500;">2</span>
<span style="color: #ff4500;">3</span></pre></div></div>

<p>Encore mieux, on peut utiliser « ** » pour forcer l&#8217;unpacking des dictionnaires. Les valeurs du dictionnaires deviennent les valeurs des paramètres, mais cette association se fait par nom : chaque clé du dictionnaire doit correspondre à un nom de paramètre. Ainsi :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> elements = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;elem1&quot;</span> : <span style="color: #483d8b;">&quot;eau&quot;</span>, <span style="color: #483d8b;">&quot;elem2&quot;</span> : <span style="color: #483d8b;">&quot;feu&quot;</span>, <span style="color: #483d8b;">&quot;elem3&quot;</span> : <span style="color: #483d8b;">&quot;air&quot;</span><span style="color: black;">&#125;</span>
 <span style="color: #808080; font-style: italic;"># les clés ont le bon nom</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>elements<span style="color: black;">&#41;</span>
eau
feu
air</pre></div></div>

<p>Si une clé ne possède pas le nom adéquat, tout plante :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> elements = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;elem1&quot;</span> : <span style="color: #483d8b;">&quot;eau&quot;</span>, <span style="color: #483d8b;">&quot;elem2&quot;</span> : <span style="color: #483d8b;">&quot;feu&quot;</span>, <span style="color: #483d8b;">&quot;rien_a_voir&quot;</span> : <span style="color: #483d8b;">&quot;air&quot;</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>elements<span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: afficher_trois_elements<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;">'rien_a_voir'</span></pre></div></div>

<p>Une autre erreur courante est d&#8217;utiliser « * » avec un dictionnaire. Dans ce cas l&#8217;unpacking fonctionne, mais comme itérer sur une dictionnaire donne une liste de clés, c&#8217;est comme si vous passiez une liste en paramètres contenant les clés :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> elements = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;elem1&quot;</span> : <span style="color: #483d8b;">&quot;eau&quot;</span>, <span style="color: #483d8b;">&quot;elem2&quot;</span> : <span style="color: #483d8b;">&quot;feu&quot;</span>, <span style="color: #483d8b;">&quot;elem3&quot;</span> : <span style="color: #483d8b;">&quot;air&quot;</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>elements<span style="color: black;">&#41;</span>
elem2
elem3
elem1</pre></div></div>

<p>Si vous donnez moins de valeurs qu&#8217;il n&#8217;y a de paramètres, Python remplit tout ce qu&#8217;il peut :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>drapeau<span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
bleu
blanc
<span style="color: #008000;">None</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> elements = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;elem1&quot;</span> : <span style="color: #483d8b;">&quot;eau&quot;</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>elements<span style="color: black;">&#41;</span>
eau
<span style="color: #008000;">None</span>
<span style="color: #008000;">None</span></pre></div></div>

<p>Dans le cas inverse – si i il y a plus d&#8217;élements que de paramètres – Python refuse les séquences, mais fait au mieux avec les dictionnaires :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> forces = <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;rouge&quot;</span>, <span style="color: #483d8b;">&quot;bleu&quot;</span>, <span style="color: #483d8b;">&quot;jaune&quot;</span>, <span style="color: #483d8b;">&quot;rose&quot;</span>, <span style="color: #483d8b;">&quot;vert&quot;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>forces<span style="color: black;">&#41;</span>
<span style="color: #008000;">TypeError</span>: afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> takes at most <span style="color: #ff4500;">3</span> arguments <span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span> given<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> elements = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;elem1&quot;</span> : <span style="color: #483d8b;">&quot;eau&quot;</span>, <span style="color: #483d8b;">&quot;elem2&quot;</span> : <span style="color: #483d8b;">&quot;feu&quot;</span>, <span style="color: #483d8b;">&quot;elem3&quot;</span> : <span style="color: #483d8b;">&quot;air&quot;</span>, <span style="color: #483d8b;">&quot;elem3&quot;</span> : <span style="color: #483d8b;">&quot;terre&quot;</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_trois_elements<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>elements<span style="color: black;">&#41;</span>
eau
feu
terre</pre></div></div>

<h3>Paramétrage dynamique</h3>
<p>Il est parfois pratique de définir une fonction qui accepte un nombre infini d&#8217;arguments. Par exemple, on a une fonction qui multiplie ses arguments entre eux :</p>

<div class="wp_syntax"><div 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> multiply<span style="color: black;">&#40;</span>a, b<span style="color: black;">&#41;</span>:
...     <span style="color: #ff7700;font-weight:bold;">return</span> a <span style="color: #66cc66;">*</span> b <span style="color: #808080; font-style: italic;"># attention, là on utilise « * » pour multiplier, ne cherchez rien de compliqué ;-)</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>multiply<span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">6</span></pre></div></div>

<p>Bien sûr, si on veut rajouter un troisième paramètre, il faut la réécrire. Pareil pour un quatrième. Finalement, on finit par demander de passer une liste pour permettre un nombre arbitraire :</p>

<div class="wp_syntax"><div 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> multiply<span style="color: black;">&#40;</span>elements_a_multiplier<span style="color: black;">&#41;</span>:
...     <span style="color: black;">res</span> = <span style="color: #ff4500;">1</span>
...     <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> elements_a_multiplier:
...         <span style="color: black;">res</span> = res <span style="color: #66cc66;">*</span> i
...     <span style="color: #ff7700;font-weight:bold;">return</span> res
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> multiply<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">24</span></pre></div></div>

<p>Et bien sachez qu&#8217;il existe une autre possibilité, autoriser l&#8217;ajout d&#8217;une infinité de paramètres ! Cela se fait bien sur avec « * ».</p>

<div class="wp_syntax"><div 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> multiply<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>tous_les_elements<span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># on ne change pas grand chose, on rajoute juste « * »</span>
...     <span style="color: black;">res</span> = <span style="color: #ff4500;">1</span>
...     <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> tous_les_elements<span style="color: black;">&#41;</span>:
...         <span style="color: black;">res</span> = res <span style="color: #66cc66;">*</span> i
...     <span style="color: #ff7700;font-weight:bold;">return</span> res
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> multiply<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
 <span style="color: #808080; font-style: italic;"># mais plus besoin d'une séquence !</span>
<span style="color: #ff4500;">26</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> multiply<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
<span style="color: #ff4500;">120</span></pre></div></div>

<p>Comment ça marche ? C&#8217;est simple, tout les arguments sont stockés dans une liste, et cette liste est le paramètre que l&#8217;on a désigné par « * ». Ce système très puissant peut être utilisé conjointement avec des paramètres normaux :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span>def afficher<span style="color: black;">&#40;</span>elem1, elem2, <span style="color: #66cc66;">*</span>elemx<span style="color: black;">&#41;</span>:
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>elem1<span style="color: black;">&#41;</span>
...    <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>elem2<span style="color: black;">&#41;</span>
...    <span style="color: #ff7700;font-weight:bold;">for</span> e <span style="color: #ff7700;font-weight:bold;">in</span> elemx :
...        <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;(*) %s&quot;</span> <span style="color: #66cc66;">%</span> e<span style="color: black;">&#41;</span>
…
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Toi&quot;</span>, <span style="color: #483d8b;">&quot;Moi&quot;</span>, <span style="color: #483d8b;">&quot;Luke&quot;</span>, <span style="color: #483d8b;">&quot;Anakin&quot;</span>, <span style="color: #483d8b;">&quot;Obi Wan&quot;</span>, <span style="color: #483d8b;">&quot;Robert&quot;</span><span style="color: black;">&#41;</span>
Toi
Moi
<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span> Luke
<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span> Anakin
<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span> Obi Wan
<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#41;</span> Robert</pre></div></div>

<p>La seule condition est de mettre « * » sur un paramètre situé après tous les autres. « * » est toujours en dernier, et il n&#8217;apparait qu&#8217;une seule fois. Enfin, il existe une convention pour le nom de cet argument : « *args ».</p>
<p>Bonne nouvelle, on peut utiliser aussi « ** ». Comme on peut s&#8217;y attendre, il permet de récupérer aussi une infinité de paramètres, mais sous forme de dictionnaire. Cela signifie qu&#8217;il ne récupère que les paramètres nommés :</p>

<div class="wp_syntax"><div 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> afficher_recette<span style="color: black;">&#40;</span>recette, <span style="color: #66cc66;">**</span>ingredients<span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># ingrédients sera un dictionnaire</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>recette<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">for</span> ingredient <span style="color: #ff7700;font-weight:bold;">in</span> ingredients.<span style="color: black;">iteritems</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: #483d8b;">&quot; - %s : %s&quot;</span> <span style="color: #66cc66;">%</span> ingredient
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> afficher_recette<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;moukraines à la glaviouse&quot;</span>,
...                             <span style="color: black;">creme</span>=<span style="color: #483d8b;">&quot;trop&quot;</span>, <span style="color: #808080; font-style: italic;"># on doit donner le nom de ce paramètre</span>
...                             <span style="color: black;">moukraines</span>= <span style="color: #483d8b;">&quot;suffisamment&quot;</span>,
...                             <span style="color: black;">glaviouse</span>=<span style="color: #483d8b;">&quot;si disponible&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># mais l'ordre des paramètres importe peu</span>
moukraines à la glaviouse
 - glaviouse : si disponible
 - creme : trop
 - moukraines : suffisamment</pre></div></div>

<p>Il faut également mettre « ** » après tous les autres arguments. La convention pour nommer ce paramètre est « **kwargs », pour « keyword arguments ».</p>
<p>Enfin, on peut mélanger tout ça d&#8217;un coup :</p>

<div class="wp_syntax"><div 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> affichage_hybride<span style="color: black;">&#40;</span>parametre_normal,
...                                   <span style="color: black;">parametre_avec_default</span>=<span style="color: #483d8b;">&quot;valeur par défaut&quot;</span>,
...                                   <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;">print</span><span style="color: black;">&#40;</span>parametre_normal<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>parametre_avec_default<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>
...     <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>kwargs<span style="color: black;">&#41;</span>
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> affichage_hybride<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;param1&quot;</span>, <span style="color: #483d8b;">&quot;param2&quot;</span>, <span style="color: #483d8b;">&quot;infini1&quot;</span>, <span style="color: #483d8b;">&quot;infini2&quot;</span>, kwinfini1=<span style="color: #ff4500;">1</span>, kwinfini2=<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
param1
param2
<span style="color: black;">&#40;</span><span style="color: #483d8b;">'infini1'</span>, <span style="color: #483d8b;">'infini2'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'kwinfini1'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'kwinfini2'</span>: <span style="color: #ff4500;">2</span><span style="color: black;">&#125;</span></pre></div></div>

<p>On doit absolument mettre les paramètres dans cet ordre :</p>
<p>1. paramètres normaux et obligatoires;<br />
2. paramètres normaux facultatifs (valeur par défaut);<br />
3. paramètres dynamiques;<br />
4. paramètres dynamiques nommés.</p>
<p>En plus, cela permet en effet de faire jouer les valeurs par défaut de manière très souple :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> affichage_hybride<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;param tout seul&quot;</span><span style="color: black;">&#41;</span>
param tout seul
valeur par défaut
<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span><span style="color: black;">&#125;</span></pre></div></div>

<p>Si vous vous sentez à l&#8217;aise avec tout ça, vous pouvez  mélanger plusieurs usages de « * » d&#8217;un coup. Je vous laisse donc en guise de conclusion un petit combo qui utilise un code précédent:</p>

<div class="wp_syntax"><div 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> multiply<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
...     <span style="color: black;">res</span> = <span style="color: #ff4500;">1</span>
...     <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> elements_a_multiplier:
...         <span style="color: black;">res</span> = res <span style="color: #66cc66;">*</span> i
...     <span style="color: #ff7700;font-weight:bold;">return</span> res
...
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>multiply<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">True</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=398</wfw:commentRss>
		</item>
		<item>
		<title>Démystifier les « raw strings » en Python</title>
		<link>http://www.e-vidence.net/?p=373</link>
		<comments>http://www.e-vidence.net/?p=373#comments</comments>
		<pubDate>Thu, 11 Feb 2010 14:12:22 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Développement]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[raw string]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=373</guid>
		<description><![CDATA[Parmi les utilisateurs de niveau intermédiaire à avancé, un des points les plus flous est souvent le concept de « raw string ». Pourtant, il n'y à rien de compliqué, mais on trouve un peu partout sur le Net des explications nébuleuses. C'est l'occasion de faire le point sur ce sujet en vérité très simple.]]></description>
			<content:encoded><![CDATA[<p>A force de donner des cours autour de Python, on finit par identifier les confusions les plus courantes. Parmi les utilisateurs de niveau intermédiaire à avancé, un des points les plus flous est souvent le concept de « raw string ». Pourtant, il n&#8217;y à rien de compliqué, mais on trouve un peu partout sur le Net des explications nébuleuses. C&#8217;est l&#8217;occasion de faire le point sur ce sujet en vérité très simple.</p>
<p>« Raw string », suggère qu&#8217;il existe un type de « chaîne brute ».</p>
<p>Coupons court à toute conception erronée. Il n&#8217;y a rien de tel.</p>
<p>Je répète.</p>
<p>Les « raw strings » n&#8217;existent pas.</p>
<h3>Ce que sont les chaînes de caractères</h3>
<p>Pour Python, dans sa petite tête de reptile automate, une chaîne est une suite de bits. Ces bits sont organisés pour former des valeurs, et chaque valeur correspond à un caractère. Cette correspondance, c&#8217;est ce qu&#8217;on appelle l&#8217;encodage. L&#8217;encodage est juste un gros tableau disant « cette valeur » vaut « ce caractère », une sorte de dictionnaire de traduction pour l&#8217;ordinateur.</p>
<p>Il existe beaucoup d&#8217;encodages différents, Windows utilise par exemple le CP-1552 tandis qu&#8217;Ubuntu utilise UTF-8. Si vous souhaitez faire de l&#8217;informatique de manière sérieuse, vous devez maîtriser le concept d&#8217;encodage et être capable de passer de l&#8217;un à l&#8217;autre. Comme ce n&#8217;est pas l&#8217;objectif de cet article, je vous renvoi à l&#8217;<a href="http://french.joelonsoftware.com/Articles/Unicode.html">excellent article</a> de Joel sur le sujet.</p>
<p>La bonne nouvelle c&#8217;est que vous pouvez comprendre la suite sans lire l&#8217;article en lien. Mais ça ne vous dispense pas de le lire plus tard.</p>
<p>Ce qu&#8217;il faut retenir c&#8217;est qu&#8217;une chaîne, en mémoire, est une suite de bits. Avec un encodage, il n&#8217;y a qu&#8217;une manière,<strong> et une seule</strong>, de représenter une donnée. Un saut de ligne ne se représente qu&#8217;avec une seule combinaison de bits possible. Un antislash et un &#8216;n&#8217; ne se représentent qu&#8217;avec une seule suite de bits possible. Et donc « \n » et saut de ligne n&#8217;ont rien en commun en mémoire.</p>
<h3>La donnée et sa représentation</h3>
<p>Il y a une subtile différence entre la donnée (la valeur d&#8217;un concept) et sa représentation (comment on décrit cette valeur). Objectivement, une donnée n&#8217;existe pas, il n&#8217;y a que des représentations, mais ça ne m&#8217;aide pas beaucoup à vous expliquer alors prenons un raccourci :</p>
<ul>
<li>La donnée, c&#8217;est ce que stocke l&#8217;ordinateur en mémoire.</li>
<li> La représentation de la donnée, c&#8217;est ce qui s&#8217;affiche.</li>
</ul>
<p>On peut représenter la même chose de plusieurs manière. Par exemple :</p>
<ul>
<li>Le chiffre « 2 » peut être représenté par « 2 », « deux », ou « II ». La donnée,  « le concept de 2 choses », est différent de sa représentation, c&#8217;est à dire ce qu&#8217;on écrit.</li>
<li> Un dictionnaire s&#8217;écrit dans le code « dict() », ou « {} » mais vous vous imaginez bien que ce n&#8217;est pas stocké ainsi en RAM. « {} » est une représentation.</li>
<li>La carte n&#8217;est pas le 	territoire.<a class="sdfootnoteanc" name="sdfootnote1anc" href="#sdfootnote1sym"><sup>1</sup></a></li>
</ul>
<p style="margin-bottom: 0.5cm;">Votre code est une représentation de ce que doit faire la machine. Ce n&#8217;est pas ce que fait la machine.</p>
<h3 style="margin-bottom: 0.5cm;">Votre ordinateur vous ment</h3>
<p style="margin-bottom: 0.5cm;">Une représentation est toujours imparfaite, et votre ordinateur vous donne des représentations pour vous donner une idée compréhensible facilement ce qui se passe. Il simplifie volontairement les choses pour vous permettre de travailler. Vous faites de même avec lui.</p>
<p style="margin-bottom: 0.5cm;">Quand vous écrivez :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">dico = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">'guido'</span>, <span style="color: #483d8b;">'language'</span>: <span style="color: #483d8b;">'python'</span><span style="color: black;">&#125;</span></pre></div></div>

<p style="margin-bottom: 0.5cm;">Vous dites à Python « créer un dictionnaire et lui associer le nom &#8216;dico&#8217; ». C&#8217;est une convention, une manière d&#8217;écrire pour lui commander une action. Ce n&#8217;est pas l&#8217;action elle même. Un dictionnaire n&#8217;est pas stocké sous forme de « {&#8217;name&#8217;: &#8216;guido&#8217;, &#8216;language&#8217;: &#8216;python&#8217;} » en RAM. Cette ligne de code est la représentation d&#8217;une action, une description de ce qu&#8217;il faut faire, mais ça reste du texte.</p>
<p style="margin-bottom: 0.5cm;">Si vous faites un « print » sur &#8216;dico&#8217;, l&#8217;interpréteur va vous afficher :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#123;</span><span style="color: #483d8b;">'name'</span>: <span style="color: #483d8b;">'guido'</span>, <span style="color: #483d8b;">'language'</span>: <span style="color: #483d8b;">'python'</span><span style="color: black;">&#125;</span></pre></div></div>

<p style="margin-bottom: 0.5cm;">L&#8217;interpréteur vous affiche une représentation d&#8217;un dictionnaire lisible pour vous, humain. Ce n&#8217;est pas ce qui est stocké en mémoire, mais ça vous donne une bonne idée de ce qui s&#8217;y trouve.</p>
<h3 style="margin-bottom: 0.5cm;">Ce que fait le drapeau « r », ou pourquoi on parle de « raw string »</h3>
<p style="margin-bottom: 0.5cm;">Il n&#8217;est pas facile de taper certains caractères, tels que les sauts de ligne. Python inclut donc un mécanisme pour les écrire facilement. Ce mécanisme est automatique, et &#8216;r&#8217; permet juste de le désactiver.</p>
<p style="margin-bottom: 0.5cm;"><em>Vous ne créez pas de chaîne. Au mieux vous donnez à Python une instruction pour qu&#8217;il le fasse pour vous.</em> Cette instruction est une réprésentation. Quand vous faites :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = <span style="color: #483d8b;">'Super chaîne avec un saut de ligne<span style="color: #000099; font-weight: bold;">\n</span>'</span></pre></div></div>

<p style="margin-bottom: 0.5cm;">A aucun moment « Super chaîne avec un saut de ligne\n » n&#8217;est la chaîne en mémoire, c&#8217;est une représentation, une instruction donnée à Python pour créer une chaîne, tout comme &#8220;{}&#8221; n&#8217;est pas le dictionnaire en mémoire.</p>
<p style="margin-bottom: 0.5cm;">Vous dites à Python « créer un objet &#8217;string&#8217; qui contient les codes des lettres &#8216;Super chaîne avec un saut de ligne&#8217; et le code d&#8217;un saut de ligne dans l&#8217;encodage courant.</p>
<p style="margin-bottom: 0.5cm;">Python ne garde pas les lettres en mémoire, mais des bits. Python ne garde pas « \n » en mémoire, mais le code pour « LF » ou « CR ».</p>
<p style="margin-bottom: 0.5cm;">« \n » ici est une représentation, une manière de dire à Python de créer une saut de ligne.</p>
<p style="margin-bottom: 0.5cm;">Si vous utilisez le drapeau (flag) « r » :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = r<span style="color: #483d8b;">'Super chaîne avec un saut de ligne<span style="color: #000099; font-weight: bold;">\n</span>'</span></pre></div></div>

<p style="margin-bottom: 0.5cm;">Ici « Super chaîne avec un saut de ligne\n » n&#8217;est pas non plus la chaîne stockée en mémoire. Tout votre code est une représentation, jamais une donnée.</p>
<p style="margin-bottom: 0.5cm;">Vous dites à Python « créer un objet &#8217;string&#8217; qui contient les codes des lettres &#8216;Super chaîne avec un saut de ligne&#8217; et le code de &#8216;\&#8217; et le code de &#8216;n&#8217;.</p>
<p style="margin-bottom: 0.5cm;">Vous lui demander de ne pas interpréter &#8216;\n&#8217; comme la représentation d&#8217;un saut de ligne, mais comme les caractères séparément. &#8216;r&#8217; dit à Python de ne pas activer la fonction qui vous permet de taper facilement des sauts de lignes et autres caractères spéciaux. Vous lui demander de ne pas interpréter l&#8217;instruction, mais de la traduire directement. <strong>Vous lui demandez de faire une traduction « brute » de la « chaîne », d&#8217;où le « raw string ».</strong></p>
<h3 style="margin-bottom: 0.5cm;">L&#8217;interpréteur, le plus gros menteur</h3>
<p>Il n&#8217;est pas facile d&#8217;afficher un saut de ligne dans l&#8217;interpréteur. Il a donc tendance à vous donner du « \n » pour vous indiquez où ils se trouvent :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> s = <span style="color: #483d8b;">&quot;Test<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #808080; font-style: italic;"># « \n » représente un saut de ligne, &quot;line break&quot; est stocké en mémoire</span></pre></div></div>

<p>Si on affiche, Python vous ressort « \n » !</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'Test<span style="color: #000099; font-weight: bold;">\n</span>'</span></pre></div></div>

<p>Python vous indique qu&#8217;il y a un saut de ligne à la fin de « Test ». Il n&#8217;a pas stocké en mémoire « \n », il essaye juste de vous aider visuellement.<br />
Pareil pour les caractères spéciaux :</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> s = raw_string<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Saisie : &quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># saisissons un anti-slash</span>
Saisie : \
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span></pre></div></div>

<p style="margin-bottom: 0.5cm;">Comme Python utilise les « \n » pour vous indiquer où sont les caractères spéciaux, il utilise aussi antislash pour vous indiquez où ils ne sont pas !</p>
<p style="margin-bottom: 0.5cm;">A aucun moment Python stocke « \\ », il ne garde en mémoire que les bits pour un seul « \ » mais le représente &#8216;\\&#8217; pour éviter les ambigüités.</p>
<h3 style="margin-bottom: 0.5cm;">Moralité</h3>
<p style="margin-bottom: 0.5cm;">Quand votre programme reçoit une chaîne en entrée, elle est déjà initialisée : qu&#8217;elle vienne du Web, de la ligne de commande ou d&#8217;un formulaire de fenêtre, c&#8217;est déjà une suite de bits qui correspond à un encodage. La chaîne ne change pas (c&#8217;est un immutable), n&#8217;est pas interprétée par Python, et un « \n » reste un « \n ».</p>
<p style="margin-bottom: 0.5cm;">Si dans le code, vous entrez des caractères spéciaux, ce sont des instructions qui disent à Python commenter créer la chaîne en mémoire. « r » dit à Python de ne pas interpréter ces notations spéciales.</p>
<p style="margin-bottom: 0.5cm;">Enfin, pour éviter la confusion, Python affiche les caractères spéciaux en utilisant la même représentation que vous utilisez dans le code. De manière amusante, c&#8217;est la partie qui amène justement le plus de confusion.<br />
<span id="more-373"></span></p>
<div id="sdfootnote1">
<p class="sdfootnote"><a class="sdfootnotesym" name="sdfootnote1sym" href="#sdfootnote1anc">1</a> - Ne 	manquez jamais de citer l&#8217;Art de la guerre en formation, c&#8217;est du 	rep farming facile.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=373</wfw:commentRss>
		</item>
		<item>
		<title>Pour qui créer l&#8217;interface ?</title>
		<link>http://www.e-vidence.net/?p=365</link>
		<comments>http://www.e-vidence.net/?p=365#comments</comments>
		<pubDate>Tue, 15 Dec 2009 13:07:51 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
		
		<category><![CDATA[Ergonomie]]></category>

		<category><![CDATA[clients]]></category>

		<guid isPermaLink="false">http://www.e-vidence.net/?p=365</guid>
		<description><![CDATA[Quand on s'occupe d'une interface, on ne peut pas la dessiner pour tout le monde, alors comment savoir pour qui optimiser l'ergonomie ?

La réponse est simple : pour ceux qui payent.]]></description>
			<content:encoded><![CDATA[<p>Quand on s&#8217;occupe d&#8217;une interface, on ne peut pas la dessiner pour tout le monde : il y a les goûts et les couleurs, mais surtout les besoins et les cas utilisateurs. Le consensus sans critique, en plus d&#8217;entrainer la mort de toute espoir de sortir du lot, finit surtout pas offrir une expérience molle car moyenne&#8230; pour tous. Il faut donc cibler.</p>
<p>Seulement comment savoir pour qui optimiser l&#8217;ergonomie ?</p>
<p>La réponse est simple : pour ceux qui payent.</p>
<p>J&#8217;entends par là que dans votre (supposée) masse d&#8217;utilisateurs, seul un petit nombre va au-delà des fonctionalités gratuites.</p>
<p>Ce petit nombre est celui qui a vraiment besoin de votre produit, c&#8217;est lui pour qui ses qualités ont de la valeur, le distingue de la concurrence et sont uniques. Si vous visez une niche, vous l&#8217;avez trouvé.</p>
<p>Considérations marketting évidentes mises à part, celà signifie que votre travail doit se concentrer sur les besoins de ces personnes, car ce sont elles qui seront fidèles et qui vont utiliser le plus le fruit de votre travail.</p>
<p>La bonne nouvelle donc, c&#8217;est qu&#8217;il suffit de commencer à faire payer quelque chose pour savoir vers quoi orienter vos efforts. La mauvaise, c&#8217;est qu&#8217;aussi bon ergonome que vous soyez, quels que soit les tests que vous ferez, votre design prendra toute sa valeur après rectifications suivant le retour de mise en production. Ne croyez pas pour autant que c&#8217;est une raison pour mettre en ligne un gruyère sous prétexte qu&#8217;on le corrigera plus tard. Mais en revanche, cela calme franchement les ardeurs des optimisateurs précoces.</p>
<p>Le deuxième effet kisscool c&#8217;est que vous allez vous apercevoir que les demandes de fonctionalité / correction de bug / [insérer ici une cause de nuit blanche] sont beaucoup plus faciles à prioriser. D&#8217;ailleurs souvent ce sont des utilisateus occasionels qui font les réclamations les plus coûteuses, et vous saurez maintenant qu&#8217;elles peuvent passer tout en bas de la pile. En revanche, en quelques heures, vous redonnerez parfois le sourire à un utilisateur assidu, et c&#8217;est la partie franchement sympa du boulot.</p>
<p>Maintenant votre mission, si vous l&#8217;acceptez, c&#8217;est de faire comprendre à votre client qu&#8217;il est dans son intérêt de vous rappeler 3-6 mois après le lancement pour passer une deuxième couche.</p>
<p>&#8230;</p>
<p>Et si notre produit n&#8217;a pas de fonctionalités payantes ? Et oui, il y a les intranets, les services publiques, les associations de bénévoles, les killer-apps sans modèle économique de start ups voués à la faillite et tout ce merveilleux écosystème qui sent bon le Web du XXIe siècle. Dans ce cas, la rentabilité n&#8217;est pas un facteur et vous devez seulement satisfaire les utilisateurs qui consomment le plus votre service (j&#8217;espère que vous n&#8217;avez pas de problème de financement&#8230;), alors un système de tracking du temps passé sur les pages et du nombre de visites sera votre meilleur indicateur.</p>
<p>Il ne reste qu&#8217;à étudier les résultats pour savoir qui se cache derrière vos fans. Leur demander directement est souvent une technique des plus efficaces. Si, si.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.e-vidence.net/?feed=rss2&amp;p=365</wfw:commentRss>
		</item>
	</channel>
</rss>
