Условное утверждение elif не дает правильных результатов

1

Elif stament должен печатать файлы журнала и путь, которые не были найдены в обычном поиске. Тем не менее, они дают каждую строку, которая просматривается в одном файле (множество информации). Что я делаю не так?

 for line in fileinput.input(walk_dir(directory, (".log", ".txt"))):
      result = regex.search(whitespace.sub('', line))
      if result:
          template = "\nLine: {0}\nFile: {1}\nString Type: {2}\n\n"
          output = template.format(fileinput.filelineno(), fileinput.filename(), result.group())

          print output
          temp.write(output)
          break
      elif not result:
          template = "\nLine: {0}\nString not found in File: {1}\nString Type: {2}\n\n"
          output = template.format(fileinput.filelineno(), fileinput.filename(), result.group())

          print output
          temp.write(output)

  else:          
      print "There are no files in the directory!!!"

Фактический код:

 elif searchType =='2':
      print "\nDirectory to be searched: " + directory
      print "\nFile result2.log will be created in: c:\Temp_log_files."
      paths = "c:\\Temp_log_files\\result2.log"
      temp = file(paths, "w")
      userstring = raw_input("Enter a string name to search: ")
      userStrHEX = userstring.encode('hex')
      userStrASCII = ''.join(str(ord(char)) for char in userstring)
      regex = re.compile(r"(%s|%s|%s)" % ( re.escape( userstring ), re.escape( userStrHEX ), re.escape( userStrASCII )))
      goby = raw_input("Press Enter to begin search (search ignores whitespace)!\n")


      def walk_dir(directory, extensions=""):
          for path, dirs, files in os.walk(directory):
             for name in files:
                if name.endswith(extensions):
                   yield os.path.join(path, name)

      whitespace = re.compile(r'\s+')
      for line in fileinput.input(walk_dir(directory, (".log", ".txt"))):
          result = regex.search(whitespace.sub('', line))
          if result:
              template = "\nLine: {0}\nFile: {1}\nString Type: {2}\n\n"
              output = template.format(fileinput.filelineno(), fileinput.filename(), result.group())

              print output
              temp.write(output)
              #break
          elif result not in line:

              output = fileinput.filename()

              print output
              temp.write(output)
              break 

      else:          
          print "There are no files in the directory!!!"
  • 8
    почему вы используете elif ? здесь достаточно простого else .
  • 1
    В блоке elif (т.е. если result равен False-ish), вызов result.group() должен вызвать исключение.
Показать ещё 4 комментария
Теги:
conditional

1 ответ

1
Лучший ответ

Вы повторяете каждую строку каждого файла, переданного fileinput.input(...), правильно? И вы выполняете оператор if для каждой строки. Если условие истинно, тогда вы break, но если условие ложно, вы не сломаетесь, а напишите в temp. Поэтому для каждой строки fileinput.input, которая не соответствует условию, вы пишете строку для temp и вывода output. (На самом деле, это неправильно - см. Править ниже).

Кроме того, elif str(result) not in line: будут иметь странные результаты - просто используйте else как предложили другие. Если в этой ситуации result оценивается как false, тогда result == None, что означает, что str(result) == 'None', что означает, что если строка содержит None, то вы получите неожиданные результаты.

Редактирование: Хорошо, на самом деле, более внимательно глядя на ваш фактический код, это неправильно, строго говоря. Но точка остается - fileinput.input() возвращает объект FileInput который по сути объединяет файлы и итерации по каждой строке поочередно. Поскольку в некоторых случаях вы не хотите выполнять действие в каждой строке, но для каждого файла, вам придется перебирать их по отдельности. Вы можете сделать это без fileinput но с тех пор, как вы используете, мы будем придерживаться следующего:

for filename in walk_dir(directory, (".log", ".txt")):
    for line in fileinput.input(filename):
        result = regex.search(whitespace.sub('', line))
        if result:
            template = "\nLine: {0}\nFile: {1}\nString Type: {2}\n\n"
            output = template.format(fileinput.filelineno(), fileinput.filename(), result.group())
            print output
            break   # (assuming you only want to print the first result)
    else:
        ouput = fileinput.filename()
        print output
        temp.write(output)
        break

Как это работает: для каждого файла в списке это печатает первое совпадение в файле или печатает имя файла, если совпадение не найдено. Вы можете использовать else с циклом for в python; блок else в конце цикла выполняется, если цикл не прерывается. Поскольку совпадение не найдено, имя файла печатается.

Если вы хотите распечатать все совпадения в файле, вы можете сохранить совпадения в списке, а вместо использования else вы можете проверить список. Упрощенный пример:

matches = []
for line in fileinput.input(filename):
    if searchline(line):
        matches.append(line)
if matches:
    print template.format(matches)
else:
    print fileinput.filename()
  • 0
    Моя слабая попытка - найти и сопоставить введенную пользователем строку в разных файлах .txt и .log, а также распечатать файл, в котором была найдена строка, и номер строки. Кроме того, я хотел напечатать файлы, где строка не была найдена / сопоставлена. Это кажется достаточно простым, но я просто врезаюсь во все виды стен. Это сложно, когда вы плохо владеете языком (Python) и его конструкциями ....
  • 0
    @ Пользователь, это не проблема. На самом деле часть того, что я сказал, была неправильной ... обновление идет.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню