Как использовать два оператора перечисления в одной функции в python?

#python #function #enumerate

Вопрос:

Я пытаюсь взять два утверждения и поместить их в одну и ту же функцию. Это часть длинного запроса для импорта списка csv-файлов (всех разной длины, верхних и нижних колонтитулов и столбцов) в один лист Excel для импорта в базу данных. Я хотел бы настроить функции, которые могут быть вызваны для оптимизации процесса.

Прямо сейчас, если я запущу следующий код, он будет работать, и я смогу использовать два параметра: начальный файл и конечный файл, чтобы определить начало и конец данных для импорта.

 beginning = 'eventID' ending = 'The Line Listing is wrong'  beginFile = 0 endFile = 0  with open("testbooklet.csv") as myFile:  for num, line in enumerate(myFile, 1):  if beginning in line:  beginFile = num   with open("testbooklet.csv") as myFile:  for num, line in enumerate(myFile, 1):  if ending in line:  endFile = num   print(beginFile,endFile)  

Однако; если я помещу это в функцию, я получу два разных сообщения об ошибке, в зависимости от того, как я пишу функцию. Для этой первой функции сообщение об ошибке выглядит следующим образом AttributeError: 'function' object has no attribute 'endFile'.

 beginning = 'eventID' ending = 'The Line Listing is wrong'  beginFile = 0 endFile = 0  # Define Function to find the first and last file lines def fileinfo(file_name):  global beginFile  global endFile    for num, line in enumerate(file_name, 1):  if beginning in line:  fileinfo.beginFile = num  # def endfileinfo(file_name):   for num, line in enumerate(file_name, 1):  if ending in line:  fileinfo.endFile = num  MyFile = open("testbooklet.csv")  fileinfo(MyFile) print(fileinfo.beginFile, fileinfo.endFile)  

Для этой функции код ошибки выглядит следующим образом: NameError: name 'endFile' is not defined

 beginning = 'eventID' ending = 'The Line Listing is wrong'  beginFile = 0 endFile = 0  def fileinfo(file_name):  global beginFile    for num, line in enumerate(file_name, 1):  if beginning in line:  beginFile = num    global endFile    for num, line in enumerate(file_name, 1):  if ending in line:  endFile = num    MyFile = open("testbooklet.csv") fileinfo(MyFile) print(beginFile) print(endFile)  

Это упрощенная версия данных, которые я использую для тестирования:

введите описание изображения здесь

Комментарии:

1. Ошибка в первой функции произойдет, если не будет найдена соответствующая строка, так как вы не назначаете или значения по умолчанию fileinfo.beginFile fileinfo.endFile .

2. Присвоение атрибутов функции не является обычным способом возврата результатов из функции. Вы должны использовать return утверждение.

3. Вы собираетесь исчерпать итератор файлов в первом цикле в версиях ваших функций. Почему бы не сделать то, что вам нужно, за один проход по файлу? Кроме того, зачем вообще использовать глобалы? Функции в python могут возвращать два числа в одной строке.

Ответ №1:

Не используйте глобальные переменные, которые изменяются функциями. Вместо этого позвольте функции возвращать все, что вам нужно, и получите обе информации за один раз:

 def fileinfo(file):  beginFile = None  endFile = None  for num, line in enumerate(file, 1):  if beginning in line:  beginFile = num  if ending in line:  endFile = num  break # No need to continue  return beginFile, endFile # return this information to caller   myFile = open("testbooklet.csv")  beginFile, endFile = fileinfo(myFile) print(beginFile, endFile)  

Ответ №2:

Не используйте две петли. Первый читает весь файл, так что второму циклу нечего читать. Вы могли бы исправить это, file.seek(0) чтобы вернуться к началу, но в этом случае нет необходимости-просто проверьте оба условия в одном цикле.

Вы также должны использовать параметры и возвращаемые значения, а не глобальные переменные.

 def fileinfo(file, beginning, ending):  beginFile = 0  endFile = 0   for num, line in enumerate(file, 1):  if beginning in line:  beginFile = num  if ending in line:  endFile = num   return beginFile, endFile  with open("testbooklet.csv") as MyFile:  begin, end = fileinfo(MyFile)