Python 2.7, используя if elif для просмотра текстового файла - PullRequest
1 голос
/ 27 января 2011

Цель состоит в том, чтобы написать скрипт, который будет копировать текстовый файл и исключать любую строку, начинающуюся с #.

У меня вопрос, похоже, я получаю ошибку индекса, которая зависит от порядка моих условий if elif,Единственная разница между нерабочим кодом и рабочим кодом (кроме суффикса "_bad" к имени неработающей функции) заключается в том, что сначала я проверяю условие "" (работает), а сначала проверяется условие "#" (не работает)

Базовый файл создается с помощью этого сценария:

>>> testFileObj = open("test.dat","w")  
>>> testFileObj.write("#line one\nline one\n#line two\nline two\n")  
>>> testFileObj.close()

Код, который работает:

def copyAndWriteExcludingPoundSigns(origFile, origFileWithOutPounds):    
    origFileObj = open(origFile,"r")  
    modFileObj = open(origFileWithOutPounds,"w")  
    while True:  
        textObj = origFileObj.readline()    
        if textObj == "":    
            break    
        elif textObj[0] == "#":    
            continue    
        else:    
            modFileObj.write(textObj)    
    origFileObj.close()    
    modFileObj.close()    

Код, который не работает:

def copyAndWriteExcludingPoundSigns_Bad(origFile, origFileWithOutPounds):  
    origFileObj = open(origFile,"r")  
    modFileObj = open(origFileWithOutPounds,"w")  
    while True:  
        textObj = origFileObj.readline()  
        if textObj[0] == "#":  
            continue  
        elif textObj == "":  
            break  
        else:  
            modFileObj.write(textObj)  
    origFileObj.close()  
    modFileObj.close()  

Что дает мне эту ошибку:

Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    copyAndWriteExcludingPoundSigns_Bad("test.dat","testOutput.dat")
  File "<pyshell#94>", line 6, in copyAndWriteExcludingPoundSigns_Bad
    if textObj[0] == "#":
IndexError: string index out of range

Ответы [ 4 ]

5 голосов
/ 28 января 2011

некоторые советы (и, пожалуйста, прочитайте PEP8 ):

  • используйте «для» вместо цикла «пока»
  • не нужно использоватьreadlines после python 2.4
  • проверить, не является ли строка пустой перед проверкой на первый символс пробелом перед '#':
    import re
    
    def copy_and_write_excluding_pound_signs(original, filtered):
        pound_re = re.compile(r'^\s*#')
        original_file = open(original,"r")
        filtered_file = open(filtered,"w")
        for line in original_file:
            if pound_re.match(line):
                continue
            filtered_file.write(line)
        original_file.close()
        filtered_file.close()
    
5 голосов
/ 28 января 2011

Если вы сделаете

if textObj[0] == "#":
и textObj = "", то в нулевом индексе не будет символа, поскольку строка пуста, следовательно, ошибка индекса.

Альтернативой является

if textObj.startswith("#"):
, который будет работать в обоих случаях.
0 голосов
/ 28 января 2011

Проблема с вашим нерабочим кодом в том, что он сталкивается с пустой строкой, которая вызывает IndexError, когда вычисляется оператор if textObj[0] == "#": ([0] является ссылкой на первый элемент строки).Рабочий код избегает этого, когда строка пуста.

Самый простой способ переписать вашу функцию - использовать for line in <fileobj>, и вам не придется беспокоиться о том, что line когда-нибудь будет пустым.Также, если вы используете оператор Python with, ваши файлы также будут автоматически закрыты.В любом случае вот что я предлагаю:

def copyAndWriteExcludingPoundSigns(origFile, origFileWithOutPounds):
    with open(origFile,"r") as origFileObj:
        with open(origFileWithOutPounds,"w") as modFileObj:
            for line in origFileObj:
                if line[0] != '#':
                    modFileObj.write(line)

Два оператора with можно объединить, но это сделало бы очень длинную и трудную для чтения строку кода, поэтому я разбил ее.

0 голосов
/ 28 января 2011

Вы должны использовать line.startswith('#'), чтобы проверить, начинается ли строка line с '#'.Если строка пуста (например, line = ''), не будет первого символа, и вы получите эту ошибку.

Также существование строки, в которой пустая строка не гарантируется,вырваться из этого цикла нежелательно.Файлы в Python являются итеративными, поэтому можно просто выполнить цикл for line in file:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...