Question

J'écris un script qui enregistre les erreurs d'un autre programme et le redémarre là où il s'était arrêté lorsqu'il rencontre une erreur. Pour une raison quelconque, les développeurs de ce programme n'ont pas jugé nécessaire d'intégrer cette fonctionnalité à leur programme par défaut.

Quoi qu'il en soit, le programme prend un fichier d’entrée, l’analyse et crée un fichier de sortie. Le fichier d'entrée est dans un format spécifique:

UI - 26474845
TI - the title (can be any number of lines)
AB - the abstract (can also be any number of lines)

Lorsque le programme génère une erreur, il vous fournit les informations de référence dont vous avez besoin pour effectuer le suivi - à savoir, l'interface utilisateur, la section (titre ou résumé) et le numéro de ligne par rapport au début du titre ou du résumé. Je souhaite consigner les phrases incriminées du fichier d'entrée avec une fonction qui prend le numéro de référence et le fichier, trouve la phrase et la consigne. La meilleure façon de le faire consiste à avancer dans le fichier un nombre de fois spécifique (à savoir, n fois, où n est le numéro de ligne par rapport au début de la section). Voici ce qui semblait logique:

i = 1
while i <= lineNumber:
    print original.readline()
    i += 1

Je ne vois pas en quoi cela me ferait perdre des données, mais Python pense que ce serait le cas, et indique ValueError: les méthodes de mélange itération-lecture perdraient des données . Est-ce que quelqu'un sait comment faire cela correctement?

Était-ce utile?

La solution

Vous obtenez ValueError car votre code contient probablement pour la ligne dans l'original: en plus de original.readline () . Une solution simple qui résout le problème sans ralentir votre programme ni utiliser plus de mémoire est en train de changer

for line in original:
    ...

à

while True:
    line = original.readline()
    if not line: break
    ...

Autres conseils

Utilisez pour et énumérer .

Exemple:

for line_num, line in enumerate(file):
    if line_num < cut_off:
        print line

REMARQUE : cela suppose que vous nettoyiez déjà les descripteurs de fichiers, etc.

.

De même, la fonction takewhile pourrait s'avérer utile si vous préférez une saveur plus fonctionnelle.

En supposant que vous n’ayez besoin que d’une ligne, cela pourrait vous aider

import itertools

def getline(fobj, line_no):
    "Return a (1-based) line from a file object"
    return itertools.islice(fobj, line_no-1, line_no).next() # 1-based!

>>> print getline(open("/etc/passwd", "r"), 4)
'adm:x:3:4:adm:/var/adm:/bin/false\n'

Vous voudrez peut-être intercepter les erreurs StopIteration (si le fichier contient moins de lignes).

Voici une version sans le motif laid avec True et sans autres modules:

for line in iter(original.readline, ''):
    if …:   # to the beginning of the title or abstract
        for i in range(lineNumber):
            print original.readline(),
        break
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top