2017-04-21 2 views
0

Ich habe den folgenden Code.Python Regex Fehler: TypeError: erwartete Zeichenfolge oder Bytes-ähnliche Objekt

import datetime 
import re 


class Entry: 
    task_name = None 
    minutes = None 
    notes = None 
    created_at = None 

    def __init__(self, task_name=None, minutes=None, 
       created_at=None, notes=None): 
     if task_name: 
      self.task_name = task_name 
      self.minutes = int(minutes) 
      self.created_at = datetime.datetime.strptime(
                created_at, 
                "%Y-%m-%d %H:%M:%S.%f") 
      self.notes = notes 
     else: 
      self.get_task_details() 

    # get task name, num of minutes and notes if required 
    def get_task_details(self): 
     self.task_name = input("Enter the name of the task: ") 
     self.minutes = self.get_minutes() 
     self.notes = self.get_notes() 
     self.created_at = datetime.datetime.now() 

    # get num of minutes and verify it 
    # the user should enter a valid input 
    def get_minutes(self): 
     while True: 
      minutes = input("Enter the number of minutes spent on the task: ") 
      if minutes: 
       try: 
        minutes = int(minutes) 
        return minutes 
       except ValueError: 
        print("Please Enter a valid num of minutes") 
      else: 
       print("Please enter a valid input. ex 12") 

    # print task info 
    def get_task_info(self): 
     print("You created your task at") 
     created_at_formatted = self.created_at.strftime("%m/%d/%Y %H:%M") 
     print("{}".format(created_at_formatted)) 

    # get notes if the user wants to 
    # else: leave it with a value of None 
    def get_notes(self): 
     answer = input("Do you want to write any note on this task ? N/y >>> ") 
     if answer.lower() == "y": 
      note = input("Enter your note >>> ") 
      return note 
     else: 
      self.notes = None 
      print("Alright. No notes are added") 

    def __str__(self): 
     return """ 
     Task Name: {} 
     Created At: {} 
     Minutes Spend: {} 
     Notes: {} 
     """.format(self.task_name, self.created_at, self.minutes, self.notes) 

class Log: 
    e = Entry() 
    entries = [] 
    entries.append(e) 

    def find_by_pattern(self): 
     """find by regex pattern""" 
     regex = input("Enter your regex >>> ") 
     try: 
      regex = re.compile(r'{}'.format(regex), re.X) 
     except sre_constants.error: 
      print("Invalid regex") 
      regex = None 
     entries_found = [] 
     # check if the user entered a regex 
     if regex: 
      for entry in self.entries: 
       if (re.findall(regex, entry.task_name) or 
         re.findall(regex, entry.notes)): 
         entries_found.append(entry) 
     else: 
      print("Please enter a valid regex") 

     if entries_found: 
      if entries_found: 
       print("We found the following entries") 
       for entry in entries_found: 
        print("{}".format(entry)) 
     else: 
      print("No entries were found based on your pattern") 

if __name__ == "__main__": 
    l = Log() 
    l.find_by_pattern() 

Wenn ich das Programm ausführen und eine Regex eingeben von: '\ w {4}'; Es stürzt Allerdings, wenn ich das Programm ausführen und geben Sie die gleiche Regex aber ohne Anführungszeichen: \ w {r}, stürzt es nicht ab. Hier ist ein klares Bild von dem, was ich zu tun versucht:

enter image description here

Antwort

1

Dies nicht wegen der regex abstürzt, sondern wegen entry.notes sein None während findall erwartet einen String.

Es funktioniert im ersten Beispiel, weil die Regex entry.task_name übereinstimmt und somit der andere Teil der Bedingungszeilen 88-89 übersprungen wird.
Wenn Sie jedoch die Anführungszeichen eingeben, stimmt die Regex nicht mit dem ersten Teil überein (es erwartet die Anführungszeichen) und stürzt bei Letzterem ab, None.

Sie können dies überprüfen, indem Sie eine Notiz eingeben, es wird nicht abstürzen, obwohl es möglicherweise klüger ist, diese Attribute zu leeren Zeichenfolgen zu initialisieren.

PS: Beachten Sie, dass Sie in get_notes die Notizen zurückgeben, falls vorhanden, aber in dem anderen Fall möchten Sie vielleicht den tatsächlichen Wert zurückgeben (oder der Wert wird gelöscht, wenn die Funktion zurückgibt und in Zeile 27 sowieso keiner setzt)

Hier ist ein schnell/schlecht feste Version:

import datetime 
import re 


class Entry: 
    task_name = "" 
    minutes = None 
    notes = "" 
    created_at = None 

    def __init__(self, task_name=None, minutes=None, 
       created_at=None, notes=""): 
     if task_name: 
      self.task_name = task_name 
      self.minutes = int(minutes) 
      self.created_at = datetime.datetime.strptime(
                created_at, 
                "%Y-%m-%d %H:%M:%S.%f") 
      self.notes = notes 
     else: 
      self.get_task_details() 

    # get task name, num of minutes and notes if required 
    def get_task_details(self): 
     self.task_name = input("Enter the name of the task: ") 
     self.minutes = self.get_minutes() 
     self.notes = self.get_notes() 
     self.created_at = datetime.datetime.now() 

    # get num of minutes and verify it 
    # the user should enter a valid input 
    def get_minutes(self): 
     while True: 
      minutes = input("Enter the number of minutes spent on the task: ") 
      if minutes: 
       try: 
        minutes = int(minutes) 
        return minutes 
       except ValueError: 
        print("Please Enter a valid num of minutes") 
      else: 
       print("Please enter a valid input. ex 12") 

    # print task info 
    def get_task_info(self): 
     print("You created your task at") 
     created_at_formatted = self.created_at.strftime("%m/%d/%Y %H:%M") 
     print("{}".format(created_at_formatted)) 

    # get notes if the user wants to 
    # else: leave it with a value of None 
    def get_notes(self): 
     answer = input("Do you want to write any note on this task ? N/y >>> ") 
     if answer.lower() == "y": 
      note = input("Enter your note >>> ") 
      return note 
     else: 
      return "" 
      print("Alright. No notes are added") 

    def __str__(self): 
     return """ 
     Task Name: {} 
     Created At: {} 
     Minutes Spend: {} 
     Notes: {} 
     """.format(self.task_name, self.created_at, self.minutes, self.notes) 

class Log: 
    e = Entry() 
    entries = [] 
    entries.append(e) 

    def find_by_pattern(self): 
     """find by regex pattern""" 
     regex = input("Enter your regex >>> ") 
     try: 
      regex = re.compile(r'{}'.format(regex), re.X) 
     except sre_constants.error: 
      print("Invalid regex") 
      regex = None 
     entries_found = [] 
     # check if the user entered a regex 
     if regex: 
      for entry in self.entries: 
       if (re.findall(regex, entry.task_name) or 
         re.findall(regex, entry.notes)): 
         entries_found.append(entry) 
     else: 
      print("Please enter a valid regex") 

     if entries_found: 
      if entries_found: 
       print("We found the following entries") 
       for entry in entries_found: 
        print("{}".format(entry)) 
     else: 
      print("No entries were found based on your pattern") 

if __name__ == "__main__": 
    l = Log() 
    l.find_by_pattern() 
Verwandte Themen