2010-10-26 13 views
9

J'écris une série d'instructions SQL dans un fichier en utilisant python. La chaîne de modèle ressemble à:Python file.write créant un retour chariot supplémentaire

store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 

J'écris au fichier comme ceci:

for line in source: 
    line = line.rstrip() 
    fields = line.split('\t') 
    script.write(store_insert % tuple(fields)) 
    script.write(os.linesep) 

Cependant, la sortie résultante, je vois \ r \ r \ n à la fin de chaque ligne, plutôt que \ r \ n comme je m'y attends. Pourquoi?

+1

La mise en forme des chaînes '%' est maintenant ancienne; l'idiome préféré est 'str.format' =) – katrielalex

+4

Avez-vous ouvert le fichier en mode texte ou binaire? Quel système d'exploitation utilisez-vous? – AndiDog

+0

Windows, et je viens de faire un ouvert (fichier, 'r') – Chris

Répondre

20

\n est converti en os.linesep pour les fichiers ouverts en mode texte. Ainsi, lorsque vous écrivez os.linesep dans un fichier en mode texte sous Windows, vous écrivez \r\n et le \n est converti en \r\r\n.

Voir aussi the docs:

Ne pas utiliser os.linesep comme une terminaison de ligne lorsque l'écriture de fichiers ouverts en mode texte (par défaut); utilisez un seul '\ n' à la place, sur toutes les plateformes.

+0

+1 bien trouvé! Cela ne se passe pas réellement pour moi (Win7), peut-être que c'est une chose dépendante de Windows? – katrielalex

+0

J'utilise aussi Windows 7, mais ça l'explique. +1 et répondez! – Chris

0

voir le open() doc: Mode valeurs

En plus de la norme fopen() peut être 'U' ou 'rU'. Python est généralement construit avec un support de nouvelle ligne universel; fournir 'U' ouvre le fichier sous forme de fichier texte, mais les lignes peuvent être terminées par l'un des éléments suivants: la convention de fin de ligne Unix '\ n', la convention Macintosh '\ r' ou la convention Windows '\ r \ n '. Toutes ces représentations externes sont vues comme '\ n' par le programme Python. Si Python est construit sans support de nouvelle ligne universel, un mode avec 'U' est le même que le mode texte normal. Notez que les objets fichiers ainsi ouverts ont aussi un attribut appelé newlines qui a une valeur de None (si aucun saut de ligne n'a encore été vu), '\ n', '\ r', '\ r \ n', ou un tuple contenant tous les types de nouvelle ligne vus.

+0

Alors quoi? Le mode de retour à la ligne universel est uniquement pour la lecture. – AndiDog

+0

@AndiDog: Je pense que ce qu'il dit c'est que quand il ouvre un fichier avec open ('', 'r') après qu'il a écrit dessus il voit \ r \ r \ n et il pense qu'il n'a écrit que ' \ r \ n '(windows), donc je lui ai dit que quand il ouvrira son fichier open() va ajouter automatiquement \ r \ n à ses données, donc' \ r \ n '+' \ r \ n '=' \ r \ r \ n ', le' \ n 'est enlevé voulez-vous que j'explique plus ??? – mouad

+1

Non J'utilise actuellement un fichier de sortie séparé ouvert avec open (fichier, 'w'). Changer pour ouvrir (fichier, 'wb') a résolu le problème, mais je ne suis pas entièrement sûr de comprendre pourquoi – Chris

1

Works pour moi:

>>> import tempfile 
>>> tmp = tempfile.TemporaryFile(mode="w+") 
>>> store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)' 
>>> lines = ["foo\t\t"] 
>>> for line in lines: 
...  line = line.rstrip() 
...  fields = line.split("\t") 
...  tmp.write(store_insert % tuple(fields)) 
...  tmp.write(os.linesep) 
... 
>>> tmp.seek(0) 
>>> tmp.read() 
"\tinsert stores (storenum, ...) values ('foo', ...)\r\n" 

Êtes-vous sûr que c'est le code qui est en cours d'exécution, ce os.linesep est ce que vous pensez qu'il est, etc?

3

Les fichiers texte ont des terminaisons de ligne différentes sur différents systèmes d'exploitation, mais il est pratique de travailler avec des chaînes ayant un caractère de fin de ligne cohérent. Python hérite de la convention de C en utilisant '\n' comme caractère de fin de ligne universelle et en s'appuyant sur les fonctions de lecture et d'écriture de fichier pour effectuer une conversion, si nécessaire. Les fonctions de lecture et d'écriture savent le faire si le fichier a été ouvert dans le mode text par défaut. Si vous ajoutez le caractère b à la chaîne de mode lors de l'ouverture du fichier, cette traduction est ignorée.

3

Avec Python 3

os.open() introduit le nouveau paramètre newline qui permet de spécifier une chaîne qui toute occurrence de \n sera traduit. La transmission d'un argument de chaîne vide newline='' désactive la traduction, laissant la nouvelle ligne char tel quel. Valide pour le mode texte seulement.

From the documentation

En sortie, si nouvelle ligne est None, tout '\ n' caractères écrits sont traduits au séparateur de ligne par défaut du système, os.linesep. Si newline est '', aucune traduction n'a lieu. Si newline est l'une des autres valeurs légales, tous les caractères \ n 'sont écrits dans la chaîne .

+0

Pour un cas d'utilisation et quelques explications, voir [ici] (http://stackoverflow.com/questions/43528959/python-3-how-to-pass-binary-file-as-text-without-saving-first) – RolfBly

Questions connexes