Возникли проблемы с str.find()
-
05-09-2019 - |
Вопрос
Я пытаюсь использовать 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
, для ваших собственных целей — это вызывает невероятную путаницу!