Вопрос

Я пытаюсь использовать str.find(), и он продолжает выдавать ошибку. Что я делаю не так?

import codecs

    def countLOC(inFile):
        """ Receives a file and then returns the amount
            of actual lines of code by not counting commented
            or blank lines """

        LOC = 0  
        for line in inFile:
            if line.isspace():
                continue
            comment = line.find('#')
            if comment > 0:
                for letter in range(comment):
                    if not letter.whitespace:
                        LOC += 1
                        break            
        return LOC

    if __name__ == "__main__":
        while True:
            file_loc = input("Enter the file name: ").strip()
            try:
                source = codecs.open(file_loc)
            except:
                print ("**Invalid filename**")
            else:
                break 
        LOC_count = countLOC(source)

        print ("\nThere were {0} lines of code in {1}".format(LOC_count,source.name))

Ошибка

  File "C:\Users\Justen-san\Documents\Eclipse Workspace\countLOC\src\root\nested\linesOfCode.py", line 12, in countLOC
        comment = line.find('#')
    TypeError: expected an object with the buffer interface
Это было полезно?

Решение

Используйте встроенную функцию open() вместо codecs.open().

Вы сталкиваетесь с разницей между не-Юникодом (Python 3 bytes, Питон 2 str) и Юникод (Python 3 str, Питон 2 unicode) строковые типы.Python 3 не выполняет автоматическое преобразование между не-Unicode и Unicode, как это делает Python 2.Использование codecs.open() без encoding параметр возвращает объект, который дает bytes когда вы читаете из него.

Кроме того, ваш countLOC функция не будет работать:

for letter in range(comment):
    if not letter.whitespace:
        LOC += 1
        break            

Этот цикл for будет перебирать числа от нуля до одного меньше, чем позиция '#' в строке (letter = 0, 1, 2...); whitespace не является методом целых чисел, и даже если бы это было так, вы не вызываете его.

Кроме того, вы никогда не увеличиваете LOC, если строка не содержит #.

«Исправленная», но в остальном точная (и неэффективная) версия вашего countLOC:

def countLOC(inFile):
    LOC = 0  
    for line in inFile:
        if line.isspace():
            continue
        comment = line.find('#')
        if comment > 0:
            for letter in line[:comment]:
                if not letter.isspace():
                    LOC += 1
                    break
        else:
            LOC += 1
    return LOC

Как я мог бы написать функцию:

def count_LOC(in_file):
    loc = 0  
    for line in in_file:
        line = line.lstrip()
        if len(line) > 0 and not line.startswith('#'):
            loc += 1
    return loc

Другие советы

Вы действительно передаете открытый файл в функцию?Может быть, попробуйте напечатать тип(файл) и тип(строка), так как здесь есть что-то подозрительное - с открытым файлом в качестве аргумента я просто не могу воспроизвести вашу проблему!(В вашем коде есть и другие ошибки, но ни одна из них не могла бы вызвать это исключение).Да, кстати, в качестве наилучшей практики НЕ используйте имена встроенных функций, например file, для ваших собственных целей — это вызывает невероятную путаницу!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top