IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Chemin d'un dossier avec accent sous windows


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Chemin d'un dossier avec accent sous windows
    Bonjour,

    je débute tout juste à apprendre la programmation avec Python. J'adore! J'ai testé la création d'un script. Le but est de renommer des fichiers en virant les accents, les caractères spéciaux, etc. L'utilisateur (moi!) lance le script et doit rentrer le chemin du dossier contenant les fichiers qu'on veut renommer. Le script marche nickel, sauf quand ledit dossier a des accents dedans. J'ai passé mon après-midi à chercher comment faire, j'ai testé des tonnes de trucs trouvés sur le net, mais je n'y arrive pas... Le programme se lance, mais quand je donne le chemin (raw_input)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C:\Users\moi\Desktop\Documents non utilisés
    , j'ai ce message:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "C:\Users\moi\Desktop\virer_accent.py", line 38, in <module>
        chemin = chemin.decode('utf-8') # pour remplacer les accents des fichiers
      File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
        return codecs.utf_8_decode(input, errors, True)
    UnicodeDecodeError: 'utf8' codec can't decode byte 0x82 in position 43: invalid start byte
    Si vous avez une idée, ce serait génial!

    merci!

    Voilà le script:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     # -*- coding: utf-8 -*-
    import os
    import unicodedata
    import re
     
    print u"\nCe script sert à remplacer:"
    print u"- les lettres accentuées par des lettres nons accentuées"
    print "- les espaces par des underscores (_)"
    print "- les lettres capitales par des lettres minuscules\n"
    print u"Les sous-dossiers sont aussi impactés\n"
    print "Pour quitter le programme, tapez 'quitter'\n"
    print "ATTENTION LE DOSSIER A TRAITER NE DOIT PAS COMPORTER D'ACCENT\n"
     
    def suppr_accent_fichiers(chemin):
        for dossier, sous_dossiers, fichiers in os.walk(chemin):   # Boucle sur chaque fichier du dossier chemin et ses sous-dossiers
            for fichier in fichiers:                           # Recupération de tous les noms de fichiers
                nomini= os.path.join(dossier, fichier)
                fichier = unicodedata.normalize('NFD', fichier).encode('ascii', 'ignore')
                fichier = fichier.lower()
                fichier = re.sub('[^a-zA-Z0-9\.]', '_', fichier)   # remplacer tous les caractères spéciaux par underscore
                while "__" in fichier:     # éviter qu'il y ait deux underscores à suivre dans les noms de fichiers
                    fichier = fichier.replace ("__", "_")
                os.rename (nomini, os.path.join(dossier, fichier))
        return
     
    def suppr_accent_dossiers(chemin):
        for dossier, sous_dossiers, fichiers in os.walk(chemin):   # Boucle sur chaque sous-dossier du dossier chemin
            for sous_dossier in sous_dossiers:                     # Recupération de tous les noms de sous-dossier
                sous_dossierini= os.path.join(dossier, sous_dossier)
                sous_dossier = unicodedata.normalize('NFD', sous_dossier).encode('ascii', 'ignore')
                sous_dossier = sous_dossier.replace (" ", "_")
                sous_dossier = re.sub('[^a-zA-Z0-9 \n\.]', '_', sous_dossier)
                sous_dossier = sous_dossier.lower()
                os.rename (sous_dossierini, os.path.join(dossier, sous_dossier))
        return
     
    chemin = raw_input("Quel est le chemin du dossier contenant les fichiers que vous voulez changer: ")
    chemin = chemin.decode('utf-8') # pour remplacer les accents des fichiers
    if chemin=="quitter":
        quit()
     
    while not os.path.exists(chemin):
        print u"Le dossier indiqué n'existe pas"
        chemin = raw_input("Quel est le chemin du dossier contenant les fichiers que vous voulez changer: ")
        chemin = chemin.decode('utf-8') # pour remplacer les accents des fichiers
        if chemin=="quitter":
            break
    else:
        print "\nen cours..."
        suppr_accent_fichiers(chemin)
        suppr_accent_dossiers(chemin)
        print u"Le script s'est déroulé avec succès"

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 776
    Par défaut
    Salut,

    Relisez les instructions intéressantes de votre code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    chemin = raw_input("Quel est le chemin du dossier contenant les fichiers que vous voulez changer: ")
    chemin = chemin.decode('utf-8') # pour remplacer les accents des fichiers
    ...
    Est ce que la chaîne de caractère retournée par raw_input est encodée utf-8? Sous Windows, c'est plutôt "cp850"

    Citation Envoyé par meazfpc Voir le message
    je débute tout juste à apprendre la programmation avec Python.
    Faciliter la i.e. des programmeurs sur le codage des chaînes de caractères est un des plus de Python3. Et comme vous débutez, vous n'avez (à priori) que de mauvaises raisons pour utiliser Python2.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    Mai 2014
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur banc de test
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 199
    Par défaut
    Bonsoir,

    Je rejoins wiztricks sur le conseil de passer à la version 3 si vous débutez et n'avez aucune contrainte professionnelle à rester sur la 2.

    Et sinon mon conseil si vous restez sur la v2 serait d'utiliser les fonctionnalités dites futures pour faciliter l'écriture et le portage futur pour la version 3.

    Pour plus d'informations : python.org/__future__

    Ne serait-ce pour unicode_literals pour éviter d'avoir à écrire u"" dans votre code.

    Ensuite pour votre problème :

    Les fonctions input() et input_raw() utilisent le flux d'échange standard stdin, tout comme print() pour stdout et stderr.

    Flux qui se comporte comme un fichier, que d'ailleurs on peut réaffecter.

    Il suffit donc de l'interroger sur l'encodage utilisée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import sys
    sys.stdin.encoding
    Sur windows en français l'IDLE retournera : 'cp1252'
    Dans la console windows en français il retournera : 'cp850' (table beaucoup plus restreinte)

    il suffit donc de décoder l'entrée par son encodage sys.stdin :

    La fonction utilise stdout pour afficher le texte passé en argument et va ensuite lire dans le stdin la valeur rentrée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # Python 2
    from __future__ import unicode_literals
     
    import sys # System-specific parameters and functions
     
    chemin = raw_input("Veuillez entrer un chemin (test: é, à, @, €): ".encode(sys.stdout.encoding, errors='ignore'))
    chemin = chemin.decode(sys.stdin.encoding)
    print(chemin.encode(sys.stdout.encoding))
    Le symbole euro n'est pas supporté par l'encodage cp850, j'ai rajouté errors='ignore' pour vérifier que sous l'IDLE il sera visible mais sous la console il ne s'affichera pas, mais le code ne plantera pas !
    On peut utiliser 'replace' pour remplacer les caractères non supportés par '?'

  4. #4
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup pour vos réponses, cela marche nickel!

    Mon script est fait avec python 2.7... Mais je vais essayer de basculer en version 3.

    Ca change beaucoup de chose? Un script en 2.7 ne marche pas en 3? Si c'est le cas, existe-t-il des sortes de convertisseurs?

    Cordialement

Discussions similaires

  1. [CDT]C++ avec Eclipse sous Windows
    Par Invité dans le forum Eclipse Java
    Réponses: 8
    Dernier message: 22/10/2004, 08h32
  2. attaquer base sql server avec easyphp sous windows
    Par jarod71 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 11/12/2003, 14h17
  3. Besoin d'aide avec postgresql sous windows NT
    Par Chihuahua dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/07/2003, 08h29
  4. PB : affichage de données avec accent sous delphi 6
    Par kinda dans le forum Débuter
    Réponses: 3
    Dernier message: 03/07/2003, 13h19
  5. Utiliser Borland C++ avec Emacs sous Windows
    Par Eikichi dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/03/2003, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo