PROJET AUTOBLOG


Sam et Max

source: Sam et Max

⇐ retour index

La différence entre __new__ et __init__ en Python

vendredi 11 janvier 2013 à 11:06

Les méthodes __new__ et __init__ n’ont rien de spécial. Ce sont des méthodes ordinaires. Mais parce qu’elles sont nommées ainsi, Python les détecte et les appelle automatiquement a un moment précis.

Ce moment, c’est ce qui différencie __init__ de __new__.

__init__ pour initialiser

__init__ est la méthode qui va être appelée automatiquement après qu’un objet ai été crée. Ce n’est pas un contructeur du tout, c’est un initialiseur.

Si vous faîtes ça:

>>> class Premiere(object):
...         
...         def __init__(self, prix):
...                 print "%s euros" % prix
...         
>>> c = Premiere(10000)
10000 euros

A la ligne c = Premiere(10000), Python va créer une instance de la classe Première(). Il va ensuite immédiatement et automatiquement appeler __init__ en lui passant cette instance en premier argument et les paramètres passés par l’appel Premiere(paramètres). Donc, quand __init__ est appelé, l’objet instancié existe déjà.

On va utiliser __init__ pour initialiser l’objet, c’est à dire pour lui donner son état de départ: changer les attributs, configurer l’objet par rapports aux arguments, etc.

Dans tous les autres langages, on utiliserait le constructeur pour faire ce boulot. Pas en Python.

L’avantage de __init__, c’est qu’il est très facile à manipuler. Il n’y a pas de magie dangereuse dans __init__: on a l’objet tout neuf, et les arguments passés à l’instancitation, on peut donc manipuler l’objet sans se soucier du reste. Ici on attache deux attributs à l’instance self:

 >>> class Premiere(object):
...         discount = False
...         def __init__(self, prix):
...                 self.prix = prix
...                 if self.prix < 5000:
...                     self.discount = True
...         
>>> c = Premiere(10000)
>>> c.discount
False

Comme en Python les attributs sont dynamiques, on peut attacher un argument même si l’instance ne le déclare pas, et il est créé automatiquement.

En résumé: __init__ est appelé automatiquement APRES la création de l’objet, et on met dedans le code d’initialisation de l’objet (généralement une modification des attributs pour leur donner leur état de départ).

__new__ pour créer

__new__ est le vrai constructeur. Pour cette raison, elle doit retourner un objet.

>>> class Premiere(object):
...
...     def __new__(cls, prix):
...        print "%s euros" % prix
...        return super(Premiere, cls).__new__(cls)
...
>>> c = Premiere(10000)
10000 euros

__new__ est appelée AVANT la création de l’objet, car c’est son boulot de créer l’instance et de la retourner. Comme on ne sait pas retourner une instance nous même (enfin si, mais pas dans cet article :-)), on appelle super() pour utiliser la méthode __new__ de object et créer une instance pour cette classe.

L’objet créé sera ensuite passé à __init__ automatiquement par Python.

On utilise rarement __new__. Les deux cas principaux sont:

En résumé: __new__ est le vrai constructeur, il est appelé pour créer l’objet, et l’objet ainsi instancié est passé à __init__. Vous n’avez presque aucune raison de vous en servir, c’est vraiment pour les cas particuliers.

Voici l’ordre d’éxécution:

>>> class Premiere(object):
...         def __new__(cls, prix):
...                 print "__new__"
...                 return super(Premiere, cls).__new__(cls)
...         def __init__(self, *args):
...                 print "__init__"
 
>>> c = Premiere(10000)
__new__
__init__

Exemple d’utilisation de __new__

Généralement on sait très bien utiliser __init__, mais __new__ est moins évident.

L’usage le plus fréquent de __new__ quand on hérite d’objets immutables. Par exemple, si vous voulez faire un objet Temperature qui hérite de float et qui accepte une unité en plus, ceci ne va pas marcher:

class Temperature(float):
 
    def __init__(self, value, unit):
 
        super(Temperature, cls).__init__(value)
        self.unit = unit
 
    def __str__(self):
        return "%s%s" % (self.value, self.unit)
 
print Temperature(10, '°C')
 
Traceback (most recent call last):
  File "<ipython-input-1-65b676255e09>", line 11, in <module>
    Temperature(10, '°C')
TypeError: float() takes at most 1 argument (2 given)

La raison est que du fait de la nature immutable de float, il est initialisé dans __new__, et il n’attend aucune valeur de plus dans __new__, mais on lui passe malgré tout (via Temperature(10, '°C')).

En revanche, ceci va marcher:

class Temperature(float):
 
    def __new__(cls, value, unit):
 
        instance = super(Temperature, cls).__new__(cls, value)
        instance.unit = unit
        return instance
 
    def __str__(self):
        return "%s%s" % (super(Temperature, self).__str__(), self.unit)
 
print Temperature(10, '°C')
10.0°C

Comme on override __new__, on lui donne la possibilité d’accepter une argument de plus.

Un autre exemple serait de vouloir créer une chaîne de caractères qui est toujours en majuscule (ce qui est bien moins utile que l’exemple précédent):

class CapsLockString(str):
 
    def __init__(self, value):
 
        print value # et maintenant je fais quoi ?
 
print CapsLockString('test')
test
test

Ça ne plantera pas, mais il n’y a rien que nous puissions faire car str est immutable. On ne peut tout simplement pas faire quoique ce soit avec value. Avec __new__, on peut faire quelque chose sur la chaîne intermédiaire:

class CapsLockString(str):
 
    def __new__(cls, value):
 
        return super(CapsLockString, cls).__new__(cls, value.upper())
 
print CapsLockString('test')
TEST

Deux chaînes sont en fait créées, une normale, puis une en majuscule retournée par upper() qui va servir de valeur à notre objet (en fait il y en a même 3 dans l’implémentation CPython, c’est pour ça que les notations littérales sont plus rapides que l’usage des classes pour créer des built-in).

__new__ permet donc essentiellement de créer de jolis API. On l’utilise par ailleurs dans les metaclasses, mais ce sera pour un autre article.

Un troisième usage de __new__, assez rare (mais en même temps utiliser __new__ est déjà rare), c’est le pattern factory. Les javaistes le connaissent bien, c’est un motif de conception qui permet de gérer la création d’objets qui peuvent eux même créer des objets, qui créer des objets qui… Bref.

Car en fait __new__ peut retourner n’importe quoi. Il peut retourner toujours la même instance pour faire un singleton par exemple. On peut même carrément renvoyer un truc qui n’a rien n’a voir, par exemple une fonction :

class FonctionFactory(object):
 
    def __new__(self, value, repeat):
 
        def repeater(string=value):
 
            return string * repeat
 
        return repeater
 
 
>>> function = FonctionFactory('hello', 2) # création de la fonction
>>> print function()
hellohello
>>> print function('bonjour')
bonjourbonjour

Ici on retourne carrément une fonction, et pas du tout une instance de FonctionFactory() comme prévu. On pourrait faire ceci de manière plus simple avec de la programmation fonctionnelle, mais __new__ permet de bénéficier de tout l’outillage de la POO.

Citations sur les prostitués

jeudi 10 janvier 2013 à 17:58

C’est pas parcequ’on a rien à dire qu’il faut fermer sa gueule… Alors comme aujourd’hui j’ai pas envie de me casser le dard je vous sors une liste de citations à placer dans vos soirées mondaines… Façon puzzle…

Ma préférence allant à Monsieur Simenon:

Les filles que l’on paie ne sont pas celles qui nous coûtent le plus cher…

Alphonse Allais

Un amant, c’est de l’amour. Deux amants, c’est du tempérament. Trois amants, c’est du commerce.

Arletty

Fermer les maisons closes, c’est plus qu’un crime, c’est un pléonasme.

Auguste Renoir Racontant ses souvenirs de bordels en compagnie de ses vieux amis Alphonse Daudet et Claude Monet.

Alphonse les séduisait, Claude les émoustillait et moi j’en profitais !

Bernard Dimey

Quand on n’a que son cul, mais qu’on a la jeunesse, on a l’île aux Trésors à portée de la main.

Caroline Otero, dite “La Belle Otero”

La fortune ne vient pas en dormant seule

Elisabeth Badinter

La prostitution relève du droit chèrement acquis à disposer librement de son corps.

Étienne Rey

Il y a un amour que l’on appelle vénal pour laisser croire que l’autre ne se vend pas.

François Cavanna

Nul n’a pas le droit de critiquer les putes qui font correctement leur métier !

Frédéric Beigbeder

Tout s’achète : l’amour, l’art, la planète Terre, vous, moi.

Frédéric Dard

La prostitution marcherait moins bien si les hommes n’avaient pas besoin de se confier à tout prix.

Quand vous dégustez des tagliatelles au restaurant alors que vous auriez pu vous en faire à la maison, il ne viendrait à l’idée de quiconque de dire que vous faites quelque chose d’immoral. Par contre quand vous payez pour du sexe, tous les moralistes vous sautent sur le paletot !

Georges Clemenceau

Payer pour le sexe ? Pourquoi pas ? Vous payez bien pour Dieu !

Georges Simenon

Le jour de la Saint Valentin je n’irais pas voir une putain, parce que je n’aime pas ce mot, mais j’irais quand même… et je lui apporterai des fleurs.

Les filles que l’on paie ne sont pas celles qui nous coûtent le plus cher…

Henri Jeanson

Les prostituées sont des femmes du monde à l’état brut.

Honoré de Balzac

Toute femme a sa fortune entre ses jambes.

Jean Yanne

Ce qui distingue une putain d’une honnête femme, c’est qu’une putain fait le bonheur de beaucoup d’hommes tandis qu’une honnête femme fait le malheur d’un seul.

Il est faux de dire que pour obtenir une femme, il faut soit du temps soit de l’argent. De l’argent il en faudra toujours, par contre vous pouvez gagner du temps.

Mae West

Un homme amoureux est comme un coupon de réduction, il faut le faire passer à la caisse sans plus attendre.

Michel Simon

Il y a un point commun entre les chats et les prostituées, c’est que pour obtenir leur affection, il faut le mériter.

Molière

L’écriture ressemble à la prostitution. D’abord on écrit pour l’amour de la chose, puis pour quelques amis, et à la fin, pour de l’argent.

Paul Gavarni

Pourquoi mépriser les prostituées ? Ce sont des femmes qui gagnent à être connues.

Pierre Dac

Les femmes de mœurs légères ont parfois la tâche lourde avec les hommes de poids.

Philippe Bouvard

La prostitution est une des rares professions qui soient demeurées très artisanales en dépit du progrès technique.

Sacha Guitry

Commence jeune à payer les femmes, tu t’apercevras moins vite que tu vieillis…

Victor Hugo

La femme est obligée de choisir entre acheter un homme, ce qui s’appelle le mariage, ou se vendre aux hommes, ce qui s’appelle la prostitution.

Virginie Despentes

Quand on affirme que la prostitution est une “violence faite aux femmes”, on veut nous faire oublier que c’est la mariage qui est “une violence faite aux femmes”.

Et je concluerais:
A poil les putes !

Migrer wordpress d’un serveur à un autre – Pense-bête

mercredi 9 janvier 2013 à 09:59

Si on veut changer de serveur sans se taper la réinstall de wordpress ça peut devenir casse-tête si on oublie deux trois trucs…

Voici un petit pense-bête avec pour exemple une config Nginx / WordPress / php5-cgi sur Ubuntu.

serveura.com = serveur sur lequel se trouve l’ancien WordPress à migrer
serveurb.com = nouveau serveur qui va accueillir WordPress

1. on sauve la db et on l’upload sur le nouveau serveur (on peut le faire à la fin si le blog a pas mal d’activité)
Sur le serveur A:

mysqldump -u user_toto -ppass_toto base_a_toto > /tmp/base_a_toto.sql
rsync -P -azc /tmp/base_a_toto.sql user@serveurb.com:/tmp/base_a_toto.sql

2. On copie wordpress sur le nouveau serveur
Sur le serveur A:

rsync -P -azc /home/monsite/wordpress/ user@serveurb.com:/home/monsite/

3. Setup et configuration du nouveau serveur
Sur le serveur B:
Installer les packets necessaires:

apt-get install php5-cgi php5-mysql mysql-server nginx spawn-fcgi sendmail

Il faut lancer les services nginx et spawn-cgi (pour ce dernier on peut utiliser supervisord)

Nginx:
Editer le fichier /etc/nginx/conf.d/monsite.conf . Attention à bien indiquer le chemin absolu vers votre site pour root

server {
    listen      80;
    server_name  monsite.com www.monsite.com;                   # your domain name
    root         /home/monsite/wordpress;  # absolute path to your WordPress installation
    index index.php index.html;
 
    error_log "/var/log/nginx_error.log";
    access_log  "/var/log/nginx_access.log";
 
    try_files $uri $uri/ /index.php;
 
    location ~ \.php$ {
        include        /etc/nginx/fastcgi_params;
        fastcgi_pass   127.0.0.1:53217;
        fastcgi_index index.php;
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }
 
location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
}
 
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
}
 
# Deny access to any files with a .php extension in the uploads directory
location ~* ^/wp-content/uploads/.*.php$ {
        deny all;
        access_log off;
        log_not_found off;
}
 
# Deny access to any files with a .php extension in the uploads directory for multisite
location ~* /files/(.*).php$ {
        deny all;
        access_log off;
        log_not_found off;
}
 
}

Spawn-Fcgi: C’est lui qui va lancer php5-cgi pour faire la liaison entre php et nginx. on va le lancer avec supervisor comme si c’était un service mais mieux.

Installation de Supervisor:

apt-get install python-setuptools
easy_install supervisor
echo_supervisord_conf > /etc/supervisord.conf

Editez le fichier /etc/supervisord.conf pour y rajouter spawn-fcgi, c’est mieux de lancer php5-cgi avec un user autre que root (www-data ou autre) :

[program:php5-cgi]
command=/usr/local/bin/spawn-fcgi -n -a 127.0.0.1 -p 53217 -u www-data -f /usr/bin/php5-cgi
redirect_stderr=true 
stdout_logfile=/var/log/php5-cgi.log
stdout_logfile_maxbytes=10MB

Pour lancer Spawn-fcgi:

supervisorctl restart php5-cgi

Mysql: on ajoute mysql au demarrage et on le lance

chkconfig mysql on
service mysql start

Dump de la DB: il faut créer un user et une base sur la nouvelle install, si possible le même que sur l’ancien serveur pour faciliter la transition.
Sur le serveur B:

mysql -u root -prootpass
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.5.28-0ubuntu0.12.04.3 (Ubuntu)
 
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> create database base_a_toto;
Query OK, 1 row affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON base_a_toto.* TO "user_toto"@"localhost" identified by "pass_toto";
 
Query OK, 0 rows affected (16.16 sec)
 
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Et on importe la base de données de serveura.com:

mysql -u user_toto -ppass_toto base_a_toto < /tmp/base_a_toto.sql

4. Changer les dns
des fois on oublie :) alors changez les dns et attendez un peu, normallement ça devrait crystalliser…

Ca prend pas 5 minutes, même avec les paquets tous prêts. on peut avoir de mauvaises surprises en route. Moi par exemple erreur 500 , pour m’aperçevoir au bout de 2 heures que j’avais pas installé php5-mysql d’où ce tuto ;)

Le cadeau de Noël est arrivé

mercredi 9 janvier 2013 à 09:00

Foxmask avait été choisit par notre tirage au sort à l’arrache. Max et moi avions opté pour lui offrir un Razer Orochi car j’en possède une depuis pas mal de temps et :

Photo de la souris Razer Orochi

Elle a toutes les qualités d'une souris de bureau ET de nomade: taille, poids, précision, autonomie...

La livraison a par contre été plus longue que prévue.

Sam et Max se décarcassent expressément

  • Max: J’ai l’impression que Paypal a fait un mix entre l’adresse de livraison et l’adresse de facturation. Ca passera jamais…
  • Sam: Mais nannnnnnnnnnn. T’es pessimiste !

Une demi-heure plus tard Razer (société américaine qui nous livrera depuis l’Allemagne), nous appelle en français pour nous demander de confirmer l’adresse. 5 minutes après je reçois un mail de confirmation de commande. 12 heures après une confirmation de shipping avec numéro de suivit. Les mecs sont hyper pros.

Après 11 jours, rien.

Je check sur le site de DHL, apparemment le colis est bloqué dans la grande ville la plus proche et le site crie en rouge de contacter DHL pour résoudre un problème d’adresse.

Je tente de les appeler. Or DHL est une entreprise internationale qui gère du courrier. En période de fête, son activité explose. Que fait DHL France, comme tout service français en cas de surcroît d’activité ? Ils embauchent du personnel mettent tout le monde en vacances.

Impossible d’avoir DHL pendant 5 jours de musique d’attente.

Finalement, ils me répondent que non, ils n’ont pas de problème d’adresse, mais que ça doit être leur sous-traitant qui a le problème. Car DHL ne livre pas partout directement, et notre colis a été remis à une autre société.

Ducros-Express.

J’ai cru à une blague, mais non, ils ont un site Web très 1995 (créé avec FrontPage si vous regardez les sources).

J’essaye de joindre, Ducros-Express, donc. Non sans noter la nouvelle référence client qui n’est pas la même que celle de DHL. Appel, sonnerie d’attente, j’apprends que “Ducros-Express, it’s more that 3000 professionals to support you around the world” (ouai, en anglais, si, si) mais qu’ils sont tous en vacances. Car c’est les fêtes, que leur activité explose, et que comme toute entreprise française…

Bref.

Je les appelle hors fête, me heurtant plusieurs fois au fait qu’ils sont pas dispo le midi. Car quand on a “3000 professionals around the world” et qu’on fait de la livraison Express, on a des horaires 9h-12h, 14h-17h. Logique.

Une fois que je les ai au téléphone, ils me répondent que non, ils n’ont pas de problème d’adresse, mais que ça doit être leur sous-traitant qui a le problème. Car Ducros-Express ne livre pas partout directement, et notre colis a été remis à une autre société.

Quercy-Messagerie.

Je crois a une blague, mais non, ils ont un site Web ils sont enregistrés à la chambre de commerce.

Je les appelle, réponse immédiate de Janine, qui n’est pas around the World mais qui connaît bien son boulot. Non y a pas de problème d’adresse. On peut vous livrer demain vers 14h ?

10h du mat, un homme avec un mélange d’accent local et lointain me téléphone. Oui il sait très bien où c’est, c’est en dessous de chez M. X (WTF ? Comment il sait ça ? C’est un lieu dit avec 100 habitants à 10 bornes de toute ville). Faudra descendre en bas de la pente car le camion passera pas. J’arrive dans 15 minutes.

Récupération du colis, reconditionnement bonbon + capote + pillule de viagra. Reexpédition vers l’adresse de Foxmask (je saiiiiiiiiiiiiiiiiiiiis où tu habiiiiiiiiiiiiiiiiiiiiiiiiiiiiiite).

Ta da :

Photo de bonbons

La fraise tagada fait un très bon papier à bulle.

Photo de boite de Razer Orochi

Il manque la pillule de viagra, qui a du tombé dans les bonbons. Que ses gosses ont bouffé...

Le reste sur le blog de foxmask.

ça va trancher chérie

mardi 8 janvier 2013 à 20:46

on va bouger le site de serveur dans les jours qui viennent alors attendez-vous à voir des trucs disparaitre parce que je vais faire ça comme un gros porc ;)

I'm richer than you! infinity loop