Sam & Max » fichier http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Appliquer un traitement à tous les fichiers d’un dossier en Python 5 http://sametmax.com/appliquer-un-traitement-a-tous-les-fichiers-dun-dossier-en-python/ http://sametmax.com/appliquer-un-traitement-a-tous-les-fichiers-dun-dossier-en-python/#comments Wed, 15 Oct 2014 08:35:58 +0000 http://sametmax.com/?p=12456 Opération courante en informatique et on a tous eu besoin de chercher comment faire une fois.

Soit l’arborescence :

test
├── dossier
│   ├── fichier.py
│   ├── fichier.txt
│   └── pas_un_dossier.txt
├── Dossier
│   ├── dOssier
│   │   └── faichier
│   └── fichiiiiiiiiier
├── .fichier
├── fichier
├── fIchier
└── Fichier

Lister le contenu d’un dossier

>>> import os
>>> os.listdir('.')
['dossier', 'Dossier', 'fichier', 'fIchier', '.fichier', 'Fichier']

On récupère les noms des dossiers et les fichiers, y compris cachés, mais pas les dossiers spéciaux types .. et ..

Le type des noms retournés est str que ce soit en Python 2 ou 3. Ça a l’air cool et homogène comme ça, jusqu’à ce qu’on se souvienne que str sont des bits en Python 2 et de l’unicode en Python 3. Donc gaffe quand vous portez votre code d’une version à l’autre. Les noms de fichiers contiennent des caractères non ASCII dans la vraie vie vivante.

Si vous voulez récupérer uniquement les dossiers ou les fichiers, il va falloir filtrer :

>>> for element in os.listdir('/tmp/test'):
...     if os.path.isdir(element):
...         print("'%s' un dossier" % element)
...     else:
...         print("'%s' est un fichier" % element)
'dossier' un dossier
'Dossier' un dossier
'fichier' est un fichier
'fIchier' est un fichier
'.fichier' est un fichier
'Fichier' est un fichier

Pareil si on veut filtrer par extensions :

>>> for element in os.listdir('/tmp/test/dossier'):
...     if element.endswith('.txt'):
...         print("'%s' est un fichier texte" % element)
...     else:
...         print("'%s' n'est pas un fichier texte" % element)
'fichier.txt' est un fichier texte
'pas_un_dossier.txt' est un fichier texte
'fichier.py' n'est pas un fichier texte

Néanmoins, Python vient avec le module glob qui permet de demander le listing du contenu d’un dossier en appliquant des filtres Unix :

>>> import glob
>>> glob.glob('/tmp/test/dossier/*.txt')
['/tmp/test/dossier/fichier.txt', '/tmp/test/dossier/pas_un_dossier.txt']
>>> glob.glob('./dossier/*.txt')
['./dossier/fichier.txt', './dossier/pas_un_dossier.txt']

Mais comme vous pouvez le voir, le comportement n’est pas le même que listdir : les éléments de la liste sont des chemins relatifs à celui passé en paramètre si il est lui-même relatif, ou absolus si celui passé en paramètre est absolu. N’oubliez donc pas de normaliser l’entrée ou la sortie avec os.path.realpath qui retournera un chemin canonique.

Même problème Python 2/3 : le type est str dans les 2 cas.

Parcours récursif

La fonction os.walk permet de lister récursivement tous les fichiers et les dossiers à partir d’un point dans l’arborescence. C’est un générateur, et sa valeur de retour est un peu particulière et se récupère via unpacking:

for dossier, sous_dossiers, fichiers in os.walk('/tmp/test'):
    print('##### %s #####' % dossier)
    print("Sous dossiers : %s" % sous_dossiers)
    print("Fichiers : %s" % fichiers)
##### /tmp/test #####
Sous dossiers : ['dossier', 'Dossier']
Fichiers : ['fichier', 'fIchier', '.fichier', 'Fichier']
##### /tmp/test/dossier #####
Sous dossiers : []
Fichiers : ['fichier.txt', 'pas_un_dossier.txt', 'fichier.py']
##### /tmp/test/Dossier #####
Sous dossiers : ['dOssier']
Fichiers : ['fichiiiiiiiiier']
##### /tmp/test/Dossier/dOssier #####
Sous dossiers : []
Fichiers : ['faichier']

Du coup, si vous voulez avoir la liste des chemin des fichiers absolus, il faut reconstituer à la main :

for dossier, sous_dossiers, fichiers in os.walk('/tmp/test'):
    for fichier in fichiers:
        print(os.path.join(dossier, fichier))
/tmp/test/fichier
/tmp/test/fIchier
/tmp/test/.fichier
/tmp/test/Fichier
/tmp/test/dossier/fichier.txt
/tmp/test/dossier/pas_un_dossier.txt
/tmp/test/dossier/fichier.py
/tmp/test/Dossier/fichiiiiiiiiier
/tmp/test/Dossier/dOssier/faichier

Encore une fois, c’est du str partout, alors attention. L’article sur l’encoding en Python reste un des plus consultés de la categ prog.

Avec une lib qui va bien

Je n’ai jamais caché mon amour immodéré pour path.py (qui enterre tous ses concurrents, dont unipath), qui encapsule toutes les opérations des fichiers de manière simple et élégante et qui marche sous Python 2 et 3.

pip install path.py

Et c’est quand même plus facile pour le parcours récursif :

>>> from path import path
>>> for f in path('.').walkfiles():
    print f
   ....:     
./dossier/fichier.txt
./dossier/pas_un_dossier.txt
./dossier/fichier.py
./Dossier/fichiiiiiiiiier
./Dossier/dOssier/faichier
./fichier
./fIchier
./.fichier
./Fichier

En plus, f est de type path sous Python 2 et 3. C’est homogène, et ça permet de faire toutes les opérations magiques que ce type permet.

Néanmoins, si vous êtes sous Python 3.4 et que vous ne voulez pas ajouter une dépendance externe, vous pouvez utiliser le module pathlib :

>>> from pathlib import Path
>>> for p in  Path('.').glob('./**/*'):
...    if p.is_file():
...        print(p)
fichier
fIchier
.fichier
Fichier
dossier/fichier.txt
dossier/pas_un_dossier.txt
dossier/fichier.py
Dossier/fichiiiiiiiiier
Dossier/dOssier/faichier
]]>
http://sametmax.com/appliquer-un-traitement-a-tous-les-fichiers-dun-dossier-en-python/feed/ 5
Ouvrir un fichier avec le bon programme en Python 16 http://sametmax.com/ouvrir-un-fichier-avec-le-bon-programme-en-python/ http://sametmax.com/ouvrir-un-fichier-avec-le-bon-programme-en-python/#comments Thu, 17 Oct 2013 10:09:59 +0000 http://sametmax.com/?p=7469 Votre logiciel doit permettre d’ouvrir un fichier avec un programme externe. Oui mais lequel ?

Les OS ont des réglages par défaut pour chaque type de fichier, et on peut demander “ouvrir le prog pour ce type de fichier par défaut”. Par exemple, moi, si je demande d’ouvrir un fichier vidéo, je m’attend à ce que VLC soit lancé.

Voilà comment faire ça en Python :

import subprocess
import sys
import os
 
def run_file(path):
 
    # Pas de EAFP cette fois puisqu'on est dans un process externe,
    # on ne peut pas gérer l'exception aussi facilement, donc on fait
    # des checks essentiels avant.
 
    # Vérifier que le fichier existe
    if not os.path.exists(path):
        raise IOError('No such file: %s' % path)
 
    # On a accès en lecture ?
    if hasattr(os, 'access') and not os.access(path, os.R_OK):
        raise IOError('Cannot access file: %s' % path)
 
    # Lancer le bon programme pour le bon OS :
 
    if hasattr(os, 'startfile'): # Windows
        # Startfile est très limité sous Windows, on ne pourra pas savoir
        # si il y a eu une erreu
        proc = os.startfile(path)
 
    elif sys.platform.startswith('linux'): # Linux:
        proc = subprocess.Popen(['xdg-open', path], 
                                 # on capture stdin et out pour rendre le 
                                 # tout non bloquant
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
    elif sys.platform == 'darwin': # Mac:
        proc = subprocess.Popen(['open', '--', path], 
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
    else:
        raise NotImplementedError(
            "Your `%s` isn't a supported operatin system`." % sys.platform)
 
    # Proc sera toujours None sous Windows. Sous les autres OS, il permet de
    # récupérer le status code du programme, and lire / ecrire sur stdin et out
    return proc

C’était le petit snippet sympas du jour !

P.S : si quelqu’un utilise BDSM BSD ou Solaris, je veux bien qu’il complète le snippet.

]]>
http://sametmax.com/ouvrir-un-fichier-avec-le-bon-programme-en-python/feed/ 16
Laissez votre clé USB se reposer avec Nitroshare 17 http://sametmax.com/laissez-votre-cle-usb-se-reposer-avec-nitroshare/ http://sametmax.com/laissez-votre-cle-usb-se-reposer-avec-nitroshare/#comments Fri, 13 Jul 2012 17:37:36 +0000 http://sametmax.com/?p=1123 Vous êtes avec votre pote/copine/collègue, chacun sur une machine différente. Vous voulez lui envoyer votre film de cul/mp3/dossier de travail. Vos choix:

  • sortir la clé USB. Efficace. Il faut juste bouger son cul pour la trouver et faire la copie 2 fois.
  • passer par le réseau local à la mano (bonne chance);
  • vous l’uploadez sur le net car vous avez du temps à perdre et la mémoire flash c’est pour les tapettes;
  • envoyez un mail. Un divx splitté par mail c’est fun.
  • vous l’envoyez par messagerie instantannée à 3Ko/s, ça risque de déco, mais au moins c’est simple.

Nitroshare propose une alternative:

  1. téléchargez ce logiciel libre pour Windows/Mac/Linux;
  2. lancez le;
  3. faites un glissé-deposé
Capture d'écran de l'usage de Nitroshare

Le dubstep de Lindsey Stirling est quelque chose qu'on a toujours envie de partager

Le principe de Nitroshare est simple: il autodétecte toutes les instances de Nitroshare sur le réseau local. C’est le même principe que Giver, sauf que contrairement à Giver, ça marche. Evidement ça implique que vous soyez tous connectés au même routeur, ce qui est presque toujours le cas à la maison ou au bureau.

On atteind pas des vitesses de folie, mais ça se fait en background, ça gère les dossiers récusivement, c’est cross plateforme et terriblement simple. Et contrairement aux disques amovibles, on ne fait la copie qu’une fois.

En conclusion, je dirais que comme c’est gratos, on peut dire que c’est nitroshare, ni pas assez.

P.S: les utilisateurs d’Ubuntu voudront sans doute utiliser un PPA:

sudo add-apt-repository ppa:george-edison55/nitroshare
sudo apt-get update
sudo apt-get install nitroshare

Si vous utilisez le deb, faudra faire un petit sudo apt-get install libqjson0 libqxmlrpc1 avant.

]]>
http://sametmax.com/laissez-votre-cle-usb-se-reposer-avec-nitroshare/feed/ 17