2010-08-24 7 views
1

J'écris un programme de python3, qui obtient les noms des fichiers à traiter d'arguments de ligne de commande. Je suis confus en ce qui concerne la façon correcte de gérer les différents encodages.arguments de ligne de commande sous forme d'octets au lieu de chaînes dans python3

Je pense que je préfère considérer les noms de fichiers sous forme d'octets et non pas des chaînes, car cela évite le danger d'utiliser un codage incorrect. En effet, certains de mes noms de fichiers utilisent un encodage incorrect (latin1 quand les paramètres régionaux de mon système utilisent utf-8), mais cela n'empêche pas les outils comme ls de fonctionner. J'aimerais que mon outil réponde à cela aussi.

J'ai deux problèmes: les arguments de ligne de commande sont donnés à moi en tant que chaînes (je l'utilise argparse), et je veux rapporter des erreurs à l'utilisateur sous forme de chaînes. J'ai réussi à adapter mon code pour utiliser des binaires, et mon outil peut gérer des fichiers dont le nom est invalide dans le codage par défaut actuel, tant qu'il est récursif dans le système de fichiers, car je convertis les arguments en binaires tôt , et utilisez des binaires lors de l'appel de fonctions fs. Lorsque je reçois un argument de nom de fichier qui est invalide, cependant, il me est transmis comme une chaîne unicode avec des caractères étranges comme \udce8. Je ne sais pas ce que c'est, et essayer de l'encoder échoue toujours, que ce soit avec utf8 ou avec l'encodage (mauvais) correspondant (latin1 ici).

L'autre problème est pour les erreurs. Je m'attends à ce que les utilisateurs de mon outil analysent mon stdout (voulant donc conserver les noms de fichiers), mais quand je rapporte des erreurs sur stderr je préfère l'encoder en utf-8, en remplaçant les séquences invalides par des caractères invalides.

Ainsi,

1) Y at-il une meilleure façon complètement différente de le faire? (oui, la correction des noms de fichiers est prévue, mais je voudrais quand même que mon outil soit robuste)

2) Comment obtenir les arguments de la ligne de commande dans leur forme binaire d'origine (non pré-décodée pour moi), sachant 3) Comment puis-je dire au codec utf-8 de remplacer des séquences invalides non décodables par une marque invalide plutôt que de mourir sur moi?

Répondre

2

Lorsque je reçois un argument de nom de fichier qui est invalide, cependant, il est remis à moi comme une chaîne de caractères unicode avec étranges comme \ udce8.

Ce sont des caractères de substitution. Les 8 bits bas sont l'octet original non valide.

Voir PEP 383: Non-decodable Bytes in System Character Interfaces.

+0

D'accord, cela s'adresse au point n ° 2. Donc le cours correct est juste d'ajouter 'surrogateescape' quand je code les arguments CLI seulement? ou gérer tout comme des chaînes en utilisant l'installation de substitution? Qu'en est-il des autres points? – b0fh

+0

Au moins ma plus grande préoccupation est adressée, alors répondez acceptée! – b0fh

+0

Python 3.1 (mais pas 3.0) devrait gérer automatiquement la surrogateescape. Traitez simplement les noms de fichiers comme des chaînes. – dan04

-1

Ne partez pas à contre-courant: les noms de fichiers sont des chaînes, pas des octets.

Vous ne devez pas utiliser un bytes lorsque vous devez utiliser un string. Un bytes est un tuple d'entiers. Un string est un tuple de caractères. Ce sont des concepts différents. Ce que vous faites est comme utiliser un entier quand vous devriez utiliser un booléen.

(à part: Python stocke toutes les chaînes en mémoire sous Unicode, toutes les chaînes sont stockées de la même manière.Codage spécifie comment Python convertit les octets sur fichier dans ce format en mémoire.

Votre système d'exploitation stocke les noms de fichiers sous forme de chaînes sous un codage spécifique. Je suis surpris que vous disiez que certains noms de fichiers ont des encodages différents; pour autant que je sache, l'encodage du nom de fichier est à l'échelle du système. Des fonctions telles que open utilisent par défaut le codage par défaut du nom de fichier du système, par exemple.

+2

Je souhaite que mon système d'exploitation considère les noms de fichiers comme des chaînes, mais il y a beaucoup de choses qui suggèrent que ce n'est pas le cas. J'essaie de lancer ls avec des paramètres régionaux différents, et cela me donne la même séquence exacte d'octets. Aucun transcodage n'est effectué si les paramètres régionaux diffèrent du codage du système de fichiers. – b0fh

+0

J'aurais utilisé des chaînes partout (c'est ce que j'ai fait en premier lieu) mais ça n'a pas fonctionné, et maintenant je pense que la raison en était que l'une des bibliothèques que j'utilise (pyxattr) échouait à gérer les substituts. – b0fh

Questions connexes