Условное утверждение elif не дает правильных результатов - PullRequest
1 голос
/ 21 июня 2011

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

 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!!!"

1 Ответ

1 голос
/ 21 июня 2011

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

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

Edit : Хорошо, на самом деле, если присмотреться к вашему фактическому коду, то, строго говоря, это неправильно.Но суть остается: 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()
...