Sam & Max: Python, Django, Git et du cul » best practice http://sametmax.com Deux développeurs en vadrouille qui se sortent les doigts du code Wed, 05 Feb 2014 14:20:37 +0000 en hourly 1 http://wordpress.org/?v=3.3.1 Exemples de bons codes Python http://sametmax.com/exemples-de-bons-codes-python/ http://sametmax.com/exemples-de-bons-codes-python/#comments Tue, 26 Feb 2013 09:47:56 +0000 Sam http://sametmax.com/?p=5127 Yeah, on a des fannnnnnns !

Ça fait quelques semaines que je me suis mis à python. J’ai commencé par des scripts (tendance sysadmin oblige) puis je me suis lancé dans des choses un (petit) peu plus importantes, notamment influencé par les cours sur la POO. Je tiens d’ailleurs à vous féliciter sur ce point, même le site du zéro n’avait jamais réussi à me les faire vraiment comprendre. Et donc, comme tout débutant qui se respecte j’essaie de faire de mon petit programme un chef d’œuvre de perfection (et il y a du boulot).

Le truc, c’est que je ne connais rien aux bonnes pratiques en python (comment commenter utilement les fonctions, les conventions de nommage, les jolies façons de coder, etc…). Je suis à la recherche d’exemples sûrs.

Connaissez-vous des librairies ou applications au code exemplaire dont je pourrais m’inspirer tant au niveau du code lui-même que de l’API ou de la doc ?

(Allez, vous devez bien en avoir à l’esprit ^^)

Bref, merci (si c’est pas pour ça c’est pour le reste) et bonne soirée !

Cher [censored],

Être placé au dessus du site du zéro provoque chez moi une érection incontrôlée. Merci.

Bonne nouvelle, il n’existe rien de tel que le code parfait, et des tas d’excellents dev font de la merde quotidiennement, ce qui permet de relativiser face à son niveau.

Maintenant, si je devais donner des exemples de code et doc dont on peut s’inspirer, je dirais :

  • les modules strings et structs de batbelt sont faciles pour commencer et propres. Le reste est moins bon car la lib est encore en alpha (mais intéressante si tu as le temps) et il n’y a pas de doc. La doc de zerobin en revanche est très bonne pour les utilisateurs (mais le code, bien que pas mauvais, n’est pas un exemple de best practice).
  • path.py a un code est très accessible qui tient dans un seul fichier, mais on peut passer beaucoup de temps dessus. Il est plein de subtilités. Les tests unitaires aussi sont simples à aborder.
  • peewee a un code compliqué et abstrait mais très propre. Bien si on veut travailler ses connaissances sur l’architecture de code.
  •  requests. Niveau avancé, mais très abordable pour un si gros projet. Excellent pour voir comment s’articule un gros truc en plein de tout petits morceaux bien techniques. La doc technique est d’un bon niveau.
  • bottle : ne regarde surtout pas le code. Mais leur doc technique est exceptionelle.
  • le module CSV de la lib standard. Il est dans ton install Python (chez moi dans /usr/lib/python2.7/csv.py). Pas mal pour voir comment ça marche en interne, et c’est un petit module pas prise de tête. Ça permet aussi de voir que ceux qui suivent les meilleurs pratiques sont pas forcément ceux qui les prêchent.

Petit rappel ceci dit : même un bon code a toujours des lacunes. Si tu prends n’importe quel bout de ces libs et le mets sur un forum, tu auras toujours un râleur pour venir débattre sur ce qu’il aurait valu mieux faire.

De plus, d’une manière générale, les gens qui publient de bons code font des trucs un peu plus compliqués qu’un simple script. Donc tu auras toujours à froncer un peu les sourcils pour comprendre. C’est normal, ne perd pas courage.

A éviter niveau code : django, bottle, twisted et les frameworks web en général. Les gros projets avec des bindings C de types sqlalchemy, qt, wx , etc. Car là on rentre dans un autre monde.

flattr this!

]]>
http://sametmax.com/exemples-de-bons-codes-python/feed/ 26
La fonction anonyme appelée immédiatement en Javascript: (function())() http://sametmax.com/la-fonction-anonyme-appelee-immediatement-en-javascript-function/ http://sametmax.com/la-fonction-anonyme-appelee-immediatement-en-javascript-function/#comments Wed, 02 Jan 2013 17:09:13 +0000 Sam http://sametmax.com/?p=3979 Javascript est un langage qui a plein d’idiomes bien à lui. En effet, c’est un langage très puissant, et ausi plein de couilles velues planquées ici et là. Les ninjas JS ont donc créée des astuces pour pallier à ces problèmes, en utilisant la force de leur outil.

Un des gros soucis en JS, c’est qu’il dépend beaucoup des variables globales, qui sont une grosse source d’ennuis en tout genre. Et il est très facile de déclarer ou d’utiliser une variable globale par erreur.

Pour limiter ce problème, on utilise la technique de la fonction anonyme immédiatement appelée. Cela fonctionne comme ceci, au lieu de faire:
pre lang=”javascript”>
alert(‘rouge’);

On fait:

(function(){
    alert('rouge');
})()

Explication pas à pas

En effet, en Javascript on peut créer une fonction sans lui donner de nom. C'est ce qu'on appelle une fonction anonyme:

function(){
    alert('rouge');
}

On peut attribuer cette fonction à une variable.

var une_variable_qui_passait_par_la = function(){ alert('rouge')};

Et derrière on peut appeler la fonction ainsi:

une_variable_qui_passait_par_la();

Mais dans notre cas, on ne met pas la fonction dans une variable, on l'enferme dans des parenthèses, ce qui garde la référence le temps de l'appeler, et on l'appelle. On fait la même chose que précédement en fait, on saute juste une étape :

(function(){ alert('rouge');})()

La référence à la fonction est perdue, on ne pourra pas l'appeler de nouveau. Mais on s'en branle fortement, on voulait juste l'appeler une fois de toute façon.

Pour rendre le code plus lisible, on le met sur plusieurs lignes:

(function(){
    alert('rouge');
})() /* on éxécute la fonction cash pistache */

Maintenant pour comprendre ce que ça fait, il faut juste réaliser que le bout de code ci-dessous fait EXACTEMENT la même chose que le bout de code juste au dessus :

alert('route');

Car on déclare la fonction, mais on l'éxécute tout de suite. Donc dans les deux cas, au chargement du script, un aura une alerte immédiatement.

Mais putain si ça fait la même chose, pourquoi tu nous gonfles avec ça ?

Parceque dans le cas du dessus ça fait la même chose, mais ça a des propriétés en plus. Vous vous doutez bien qu'on tape pas 4 lignes en trop pour le plaisir (à part en Java).

En effet, en créant une fonction, on crée un scope. Ainsi, tout ce qui est déclaré avec var dans la fonction sera garanti de ne pas être une variable globale. Pas d'effet de bord sur le monde extérieur. Et le monde extérieur n'a PAS accès aux variables déclarées dans la fonction. Par contre la fonction a accès aux variables globales !

Par exemple, dans un navigateur, vous avez toujours accès à l'objet window et l'objet Date partout dans le code.

/*
    Ici vous avez accès à window et Date
*/
 
(function(){
 
    /* Ceci ne va pas changer l'objet window en dehors de la fonction
        car on redéclare la variable, à l'intérieur du scope de la fonction.
     */
    var window = '3.1';
 
    var rideau = 'vista';
 
    /* Ici vous avez accès à Date */
 
    alert(new Date())
 
 
})()
 
/*
    Ici vous n'avez PAS accès à "rideau"
*/

Il est donc une bonne pratique de mettre TOUT son script dans une fonction qui s'auto-appelle, pour l'isoler du monde exterieur et ne pas pourrir le namespace global. Si on avait pas fait ça, et qu'un autre script définissait aussi rideau, l'un des deux aurait écrasé l'autre. Et dans tous les cas on aurait écrasé window.

Encore mieux

Comme on crée un conteneur isolé, on peut faire ce que l'on veut dedans. Et on a deux moyens de communique avec ce conteneur. D'abord, les variables globales. Ensuite, les paramètres de la fonction auto-appelée.

On peut exposer le contenu de la fonction à travers les variables globales. Par exemple, vous faites un générateur de 'pouet', chose importante s'il en est :

(function(){
 
    /* ces variables ne sont pas accessibles depuis l'extérieur */
    var pouetGenerator = {};
    var variablePrivee = true;
 
    /* ces fonctions sont accessibles seulement depuis pouetGenerator */
    pouetGenerator.fairePouet = function(){
        alert('pouet')
    }
 
    pouetGenerator.nePasFairePouet = function(){
        if (variablePrivee) {
            alert('pas pouet');
        }
    }
 
    /* On rend notre pouetGenerator accessible au reste du monde */
    window.pouetGenerator = pouetGenerator;
 
})()
 
/* On peut utiliser notre générateur de pouet partout ailleurs */
pouetGenerator.nePasFairePouet()

En effet, tout ce qui est attaché à window devient une variable globale dans un navigateur. C'est une caractéristique de Javascript dans un navigateur Web: window est un objet accessible partout, et on a accès partout à ses attributs. On a donc notre code parfaitement isolé (la seule chose exposée c'est notre point d'entrée : pouetGenerator). On ne pollue pas le namespace. En prime personne n'a accès aux variables privées comme variablePrivee;

On peut aussi utiliser les paramètres et les valeurs de retour pour cela :

/* pouetGenerator, déclaré sans "var", est une variable globale */
pouetGenerator = (function(chaine_du_pouet){
 
    /* ces variables ne sont pas accessibles depuis l'extérieur */
    var pouetGenerator = {};
    var variablePrivee = true;
 
    /* ces fonctions sont accessibles seulement depuis pouetGenerator */
    pouetGenerator.fairePouet = function(){
        alert(chaine_du_pouet)
    }
 
    pouetGenerator.nePasFairePouet = function(){
        if (variablePrivee) {
            alert('pas pouet');
        }
    }
 
    /* On rend notre pouetGenerator accessible au reste du monde
        en la retournant, ce qui va mettre la référence dans le pouetGenerator
        qui est la variable globale.
    */
    return pouetGenerator;
 
/* On passe 'pouet' en paramètre, il va se retrouver dans chaine_du_pouet */
})('pouet')
 
/* On peut utiliser notre générateur de pouet au même niveau */
pouetGenerator.nePasFairePouet()

Il y a deux différences dans ce code. La première, c'est qu'on met la variable à disposition en la retournant plutôt qu'en l'attachant à document. La seconde, c'est qu'on passe 'pouet'.

On pourrait se dire que l'interêt est limité, mais considérez l'exempe suivant:

(function($){
    $('p').css('color', 'rouge-fluo')
})(jQuery.noConflic())

jQuery.noConflic() restaure $ à sa valeur précédente, permettant à d'autres libs d'utiliser $ (comme la lib prototype.js). Mais jQuery.noConflic() retourne aussi l'objet jQuery, que l'on passe en paramètre. Ce paramètre est nommé $ dans la signature de la fonction. Dans notre fonction, on peut donc QUAND MÊME utiliser $ pour faire référence à jQuery car tout ce qui est dans la fonction est isolée du reste du monde. Et le reste du monde peut utiliser $ pour autre chose que jQuery.

Best practice

Généralement un code de production pour un script complet ressemble donc à ça:

;(function(alias){
"use strict";
 
/* tout le code du script va ici */
 
var une_variable_privee;
 
window.une_variable_exposee = 'foo';
 
})(truc_a_aliaser)

Notez le ; au début qui permet de rajouter votre script à la suite d'un autre script même si celui-ci a oublié de mettre un ; sur sa dernière ligne (utile pour les minifieurs).

Notez aussi le "use strict"; qui dit au navigateur que tout ce qui se trouve dans cette fonction devra être traité par un parseur strict qui vous signalera plus d'erreurs de code. Cela ne s'applique qu'à la fonction, laissant le reste du monde le droit d'utiliser du code moins strict.

flattr this!

]]>
http://sametmax.com/la-fonction-anonyme-appelee-immediatement-en-javascript-function/feed/ 16