Pergunta

Eu estou escrevendo um script que registra os erros de outro programa e reiniciar o programa de onde parou quando encontra um erro. Por qualquer motivo, os desenvolvedores deste programa não sentem que é necessário para colocar essa funcionalidade em seu programa por padrão.

De qualquer forma, o programa leva um arquivo de entrada, analisa-lo, e cria um arquivo de saída. O arquivo de entrada é em um formato específico:

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

Quando o programa gera um erro, dá-lhe as informações de referência que você precisa para monitorar o erro - ou seja, a interface do usuário, a seção (título ou resumo), e o número da linha em relação ao início do título ou resumo. Quero registrar as frases ofensivas do arquivo de entrada com uma função que leva o número de referência e o arquivo, encontra a sentença, e registra-lo. A melhor maneira que eu poderia pensar em fazer isso envolve a avançar através do arquivo de um número específico de vezes (ou seja, n vezes, onde n é o número da linha em relação ao início do seciton). A maneira que parecia fazer sentido para fazer isso é:

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

Eu não vejo como isso iria me tornar os dados perder, mas Python pensa que seria, e diz ValueError: Mixing iteration and read methods would lose data. Alguém sabe como fazer isso corretamente?

Foi útil?

Solução

Você começa a ValueError porque seu código provavelmente tem for line in original: além original.readline(). Uma solução fácil que corrige o problema sem fazer seu programa mais lento ou consumir mais memória está mudando

for line in original:
    ...

para

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

Outras dicas

Use for e enumerate .

Exemplo:

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

NOTA :. Isso pressupõe que você já estão limpando seus identificadores de arquivo, etc

Além disso, o TakeWhile função pode ser útil se você preferir um sabor mais funcional.

Assumindo que você só precisa de uma linha, isso poderia ser de ajuda

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'

Você pode querer erros StopIteration de captura (se o arquivo tem menos linhas).

Aqui está uma versão sem o padrão while True feio e sem outros módulos:

for line in iter(original.readline, ''):
    if …:   # to the beginning of the title or abstract
        for i in range(lineNumber):
            print original.readline(),
        break
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top