Site original : Sam & Max: Python, Django, Git et du cul
Il est de ces petits modules qui sont tout simples et bien pratiques. Et la lib standard de Python en regorge. Aujourd’hui (cette nuit, ce matin, choisissez votre référentiel, pour moi c’est le petit dej), on va voir le module tempfile
.
Il permet de manipuler des fichiers et dossiers – qui après tout sont des fichiers – temporaires, c’est à dire jetable, en quelque sorte.
Donc :
>>> import tempfile
La fonction la plus simple permet d’obtenir le dossier de l’OS dans lequel on met généralement les fichiers temporaires, comme par exemple C:\TEMP, C:\TMP, /tmp, /var/tmp, ou /usr/tmp selon la machine, l’OS, les variables d’environnement. Sur ma machine :
>>> tempfile.gettempdir() '/tmp'
Si vous avez juste besoin d’un dossier temporaire dans lequel travailler :
>>> tempfile.mkdtemp() '/tmp/tmps01VJw'
Il va être créé et sera accessible en lecture et écriture pour l’utilisateur qui l’a créé (permissions 700 sous Linux par exemple). Le chemin est retourné sous forme de string, à charge de votre programme de le supprimer, ou laisser l’OS s’en charger naturellement au prochain reboot.
Il existe plusieurs manière de créer un fichier temporaire avec ce module, mais je vous invite à utiliser principalement :
>>> f = tempfile.NamedTemporaryFile() >>> f <open file '<fdopen>', mode 'w+b' at 0x1b7fc00> >>> f.name '/tmp/tmp0FxO_c'
C’est la méthode la plus simple et la plus passe-partout. Vous pouvez oublier mktemp()
, mkstemp()
, TemporaryFile()
, etc. Le fichier est automatiquement supprimé quand vous appelez close()
dessus, à moins de passer False
via le paramètre delete
.
Au passage vous pouvez influencer le nom du fichier résultant en passant prefix
, suffix
, et dir
en arguments.
>>> tempfile.NamedTemporaryFile(prefix='~').name u'/tmp/~XAoApc' >>> tempfile.NamedTemporaryFile(suffix="tmp").name u'/tmp/tmpbirE0Jtmp' >>> tempfile.NamedTemporaryFile(suffix=".tmp").name u'/tmp/tmpm4iHXE.tmp' >>> tempfile.NamedTemporaryFile(dir="/home/sam/.tmp").name u'/home/sam/.tmp/tmpHfwhQI' >>> tempfile.NamedTemporaryFile(dir="/home/sam/.tmp").name
mode
et bufsize
sont aussi disponibles, et seront relayés à file()
sous le capot.
>>> tempfile. tempfile.NamedTemporaryFile tempfile.TMP_MAX tempfile.gettempdir tempfile.mkdtemp tempfile.mktemp tempfile.template tempfile.SpooledTemporaryFile tempfile.TemporaryFile tempfile.gettempprefix tempfile.mkstemp tempfile.tempdir >>> tempfile.get tempfile.gettempdir tempfile.gettempprefix >>> tempfile.gettempdir() '/tmp'
Une dernière astuce qui ne m’a jamais servi : tempfile.SpooledTemporaryFile(max_size=X)
. Similaire à NamedTemporaryFile
, mais le fichier est uniquement en mémoire, et sera transformé en un fichier sur le disque si sa taille dépasse X octets. StringIO
est utilisé pour la partie en RAM.
Le fait de demander son file descriptor (l’entier qui représente le fichier pour le programme) le fait aussi passer en mode “sur le disque” :
>>> a = tempfile.SpooledTemporaryFile(max_size=10000) >>> a.name Traceback (most recent call last): File "<ipython-input-43-c0a6f6c60584>", line 1, in <module> a.name File "/usr/lib/python2.7/tempfile.py", line 569, in name return self._file.name AttributeError: 'cStringIO.StringO' object has no attribute 'name' >>> a.fileno() 9 >>> a.name '<fdopen>'
Sur les décorateurs, normalement, vous avez tout ce qu’il faut pour être au point.
Néanmoins en informatique la moitié de la connaissance, c’est l’usage, pas la fonctionnalité. Car il y beaucoup d’usages auxquels on ne pense pas.
Particulièrement, je vous avais déjà expliqué que les fonctions étaient des objets comme les autres en Python, et qu’on pouvait donc les créer à la volée, les retourner, les passer en paramètre, et même leur coller des attributs.
Or les décorateurs ne sont jamais que des fonctions.
Maintenant, souvenez vous, le décorateurs property permet de faire ceci :
class Mamouth(object): _valeur = "3 calots" @property def valeur(self): return self._valeur.upper() @valeur.setter def valeur(self, valeur): self._valeur = valeur.strip() >>> bille = Mamouth() >>> bille.valeur u'3 CALOTS' >>> bille.valeur = "une pépite " >>> bille.valeur >>> print(bille.valeur) UNE PÉPITE
La syntaxe qui doit attirer votre attention est @valeur.setter
. En effet, d’où vient ce décorateur ?
On comprend mieux ce qui s’est passé avec ce test :
>>> Mamouth.valeur.setter <built-in method setter of property object at 0x1a1baf8>
setter
est tout simplement un attribut de la méthode valeur
. Par ailleurs, c’est une fonction et un décorateur.
Pourquoi faire cela ? Et bien tout simplement parce que cela permet d’attacher une fonction qui ne sert que dans un cas (ici ça ne sert qu’à créer le setter de la propriété valeur
) à son contexte.
Bien entendu vous pouvez faire ça vous même, il suffit de le vouloir très fort et de croire en le pouvoir de l’amour.
Par exemple, imaginez un décorateur qui permet d’attacher un comportement de sérialisation à une fonction. On ne veut pas modifier la fonction, mais on veut qu’elle puisse automatiquement, pour quelques caractères de plus, pouvoir aussi retourner du JSON ou du pickle.
import json import pickle def serializable(func): # Contrairement à la plupart des décorateurs, on ne va pas retourner # un wrapper, mais bien la fonction originale. Simplement on lui aura ajouté # des attributs func.as_json = lambda *a, **k: json.dumps(func(*a, **k)) func.as_pickle = lambda *a, **k: pickle.dumps(func(*a, **k)) return func
Et ça s’utilise ainsi :
import locale from calendar import TimeEncoding, day_name, day_abbr # obtenir les noms de jours localisés est complètement rocambolesque en python def get_day_name(day_number, locale, short=False): """ Retourne le nom d'un jour dans la locale sélectionnée. Exemple : >>> get_day_name(0, ('fr_FR', 'UTF-8')) 'lundi' """ with TimeEncoding(locale) as encoding: s = day_abbr[day_number] if short else day_name[day_number] return s.decode(encoding) if encoding is not None else s @serializable def get_days_names(locale=locale.getdefaultlocale(), short=False): """ Un dictionnaire contenant un mapping entre les numéros des jours de semaine et leurs noms selon la locale donnée. """ return {i: get_day_name(i, locale) for i in xrange(7)}
En usage ordinaire, la fonction retourne bien ce qui est prévu :
>>> get_days_names() {0: 'lundi', 1: 'mardi', 2: 'mercredi', 3: 'jeudi', 4: 'vendredi', 5: 'samedi', 6: 'dimanche'} >>> get_days_names(locale=('en_US', 'UTF-8')) {0: 'Monday', 1: 'Tuesday', 2: 'Wednesday', 3: 'Thursday', 4: 'Friday', 5: 'Saturday', 6: 'Sunday'}
Mais on peut choisir le format à la sortie :
>>> get_days_names.as_json() '{"0": "lundi", "1": "mardi", "2": "mercredi", "3": "jeudi", "4": "vendredi", "5": "samedi", "6": "dimanche"}' >>> get_days_names.as_pickle(locale=('en_US', 'UTF-8')) "(dp0\nI0\nS'Monday'\np1\nsI1\nS'Tuesday'\np2\nsI2\nS'Wednesday'\np3\nsI3\nS'Thursday'\np4\nsI4\nS'Friday'\np5\nsI5\nS'Saturday'\np6\nsI6\nS'Sunday'\np7\ns."
Ici, on a attacher une fonction à une autre fonction, en mettant la deuxième dans un attribut de la première.
Comme les décorateurs sont des fonctions, rien ne vous empêche de faire pareil avec un décorateur, et c’est de cette manière que @property
attache un décorateur setter
à chaque méthode.
… mais quand même. Il va falloir sérieusement étudier le passage de nos sites à pypy.
$ pypy --version Python 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08) [PyPy 1.8.0 with GCC 4.6.2] $ date; pypy -c "for x in xrange(1000000000): pass"; date mardi 9 juillet 2013, 12:30:58 (UTC+0200) mardi 9 juillet 2013, 12:31:09 (UTC+0200) $ python --version Python 2.7.3 $ date; python -c "for x in xrange(1000000000): pass"; date mardi 9 juillet 2013, 12:31:16 (UTC+0200) mardi 9 juillet 2013, 12:32:49 (UTC+0200)
Ces derniers jours, marqueurs véritables d’une productivité fulgurante de ma part m’ont ammené à me perdre sur Youtube.
En me baladant de documentaires en documentaires, sur la reproduction asexuée des anémones de mer à la dance tribale des papous d’océanie entre autre.
Je suis tombé sur un reportage qui présente Leonardounet non pas comme le super peintre que l’on connait mais sous une autre facette (en fait plusieurs mais celle-là est chouette).
Une théorie nous apprend que la Joconde serait Salai, le petit garçon amant de notre cher Leonard.
En fait si vous ne voulez pas vous taper le doc en entier je vous fais illico presto la synthèse:
Leonard De Vinci serait donc un pédophile d’1m95 qui a peint à 2 reprises son gentil petit garçon de joie dont une sous les traits de la Joconde, organisait des sodomies festives avec ses potes et collectionnait les mecs.
Des millions de personnes l’admirent, le vénèrent de part le monde, ses reliques se vendent des millions et on me dit que je suis dégueulasse quand je met le doigt dans mon nez.
C’était la minute inutile de Max. Bonne journée.
PS: On comprend mieux comment lui est venue l’idée d’inventer le sous-marin
Vous vous souvenez, 0bin, ce pastebin chiffré côté client écrit en Python ? Le but était de protéger, non pas l’utilisateur, mais l’hébergeur, d’une attaque en justice. La théorie est qu’il ne peut en effet être tenu de modérer ce qu’il ne peut consulter.
Et bien on vient de recevoir notre première demande légale de retrait de liens.
Petit retour sur les faits, pistes de réflexion et appel à commentaires.
La demande ne nous est pas parvenue directement, ni même par notre hébergeur, mais via notre fournisseur de nom de domaine, en l’occurrence pour 0bin.net, l’américain namecheap.
Techniquement, nous ne sommes pas aux USA, et nos serveurs ne le sont pas non plus. Pour Max, “c’est idiot de se prendre un procès pour un site qui rapporte pas”. Moi je dirais plutôt que le risque, c’est de perdre le nom de domaine qui est quand même super cool, mais ma première réaction a plutôt été “nannnnnnn, faut pas censurer”. Au final, on quand même retiré les pastes, puisqu’ils contenaient des liens de téléchargement de contenus protégés par le droit d’auteur.
Voici les demandes que nous avons reçu :
2.) Identify the copyrighted work claimed to have been infringed
You link to this copyrighted material (music albums):DANNY PRESZ – Inicio – (2013)
ORQUESTA BRONKO & SHAKAITO – 30 Aniversario-Homenaje – (2013)
CHARLIE CRUZ – Huellas – (2013)
MONGORAMA – Baila Que Baila – (2013)
CONJUNTO SABROSURA – Moña Pa’ Mi Bongó – (2013)
V. A. – Sergio George’s Salsa Giants – (2013)
Victor Manuelle – Me Llamaré Tuyo – (2013)3.) Provide us the exact location of the infringing file with the exact link
On your servers here (re-directing to 180upload.com):http://0bin.net/paste/7eefb6647bb1e606ef95eaa219e4f2de8ef98d5a#GipoKK++q7p3t+56MQPQa7Tm50Vq3BTATm0a9CsiBE0=
http://0bin.net/paste/d3d3db7281b32d1d9ba4be1f0166c0e6681b7904#yuYfcO5g83WDQ7xgF8l39AhHJH4N+XfzMv6Th1IoiVo=
http://0bin.net/paste/4185de7d1d5acc69f149472edb6395603786e622#s22bq9IkdWlm7vajb4+ryNvQLAe79tYZqrICzaexw1E=
http://0bin.net/paste/df3bf3537bec0d54c1fc2d469307d91674172072#uTszh1/Om8baR/hsvWpLyMm50vgwRoRRsMkMbgVouTo=
http://0bin.net/paste/1cbb4a2796db7015412353e9cc6818cd16673338#spj9KqFNfCeMR/VNN5IVof4Sax9njevkcIBuesNWTmE=
http://0bin.net/paste/f67fd84d81bdfeb5da8a529a1064d143c8831fe6#uadJcY9uIaGbJ7oXUZ8kcXXpiktHjwkhE9XUH3TC+9U=
http://0bin.net/paste/a1043ecdf4fe1d1a4d55aedc5d9409f1767223ef#QaT1pCopGaxs9ZC07N+0cmVg6aRoiL9uY3GOPvuUx7w=
4.) Provide us the web address under which the link has been published
The links are shared here in public:http://bypachayo.blogspot.de/
J’ai groupé les mails en un seul, mais il y en a eu 3. Notez qu’ils avaient accès aux liens avec la clé de chiffrement, puisqu’ils étaient posté publiquement sur un blog. De plus, l’identification a probablement été manuelle étant donné la nature de 0bin.
0bin n’est pas un outil de lutte contre la censure ou de contournement légal. Il n’est pas armé pour le cas où la demande de take down arrive avec le lien complet, clé incluse, car il a été exposé ainsi sur le Net.
Il ne permet pas non plus de prévenir l’utilisateur du retrait de ses liens : tout le monde va tomber sur une 404 jusqu’à ce que l’auteur soit averti, et il ne comprendra pas ce qui s’est passé.
Ici, on a eu la chance d’avoir un seul blog, donc je suis allé poster un commentaire dessus pour lui expliquer la situation. Mon espagnol est un peu rouillé d’ailleurs.
On voit aussi que 0bin, et Internet en général, est mal compris : le mec utilisait l’outil pour poster un lien par paste, qu’il linkait ensuite sur son site. Qu’espérait-il ? Camoufler quelque chose ? A-t-il compris comment marchait le service ? A quoi il était destiné ?
La seule bonne nouvelle dans tout ça, c’est qu’on a rajouté un script qui supprime permet de supprimer un paste en Python.
Même si les liens étaient illégaux (d’ailleurs je n’ai aucune connaissance pour vérifier que l’injonction de retrait est elle, légale), cela fait toujours un peu chier de devoir retirer quelque chose. Cette fois, on n’a pas recopié l’information ailleurs, mais peut être qu’on aurait dû.
La vraie question c’est : est-ce qu’on veut ajouter des fonctionnalités de résistance contre la censure à 0bin ? Est-ce que ce but est vraiment complémentaire à l’objectif initial ? Est-ce que les utilisateurs en ont besoin ? Est-ce que ça ne va pas transformer le logiciel en un truc qui n’a rien à voir ?
Et si oui, que mettre en place ? De mon chapeau, j’ai déjà quelques idées :
Mais rien de tout ça ne règle le problème de notre cher fan de Danny Presz. D’ailleurs faut-il résoudre son problème ? Et si oui, est-ce le rôle de 0bin ?
J’ai horreur de terminer une article comme ça, ça fait vraiment pute à commentaires sur un blog cheap, mais qu’est-ce que vous en pensez ?