我有这样的代码:
from datetime import datetime
from tabulate import tabulate
def search_projection_date():
projections = open('projections.txt','r').readlines()
date = input("Input projection date: ")
try:
date = date.strptime(date, "%d.%m.%Y.")
except:
print("Date input error!")
#search_projection_date()
for i in projections:
projections = i.strip("\n").split("|")
if date == projections[2]:
table = [['Code:',projections[0]],['Hall:',projections[1]],['Date:',projections[2]],['Start time:',projections[3]],['End time:', projections[4]],['Day(s):', projections[5]], ['Movie:', projections[6]], ['Price:', projections[7]]]
print (tabulate(table))
#break
else:
print("No projection on that date")
和这样的文本文件:
0001|AAA|17.12.2017.|20:30|21:00|sunday|For a few dolars more|150
0002|BBB|17.12.2017.|19:30|21:15|saturday|March on the Drina|300
0003|GGG|19.12.2017.|18:00|19:00|tuesday|A fistful of Dolars|500
0004|GGG|16.12.2017.|21:15|00:00|sunday|The Good, the Bad and the Ugly|350
我尝试按日期搜索电影投影...
如果在输入的日期有投影,它将找到它并打印列表,但在打印该列表之前,它将始终打印“日期输入错误”,并在该列表之后“在该日期没有投影”。 (如果我将break
放在if
语句中,它将仅打印输入日中的第一个找到的投影,而不是else
语句,显而易见的)
问题:如果正确输入日期,如何仅打印没有“日期输入错误”的投影列表。
如果日期正确但没有投影以及如何在正确输入之前询问用户输入,如何仅打印“该日期无投影”?通过这种递归方式,它将始终抛出异常和递归search_projection_date()
函数。
答案 0 :(得分:3)
您的代码存在一大堆重大问题。事实上,他们展示了为什么我们经常听到的一些一般性建议实际上是一个很好的建议。
date = input("Input projection date: ")
行创建一个名为date
的字符串。 input
始终返回一个字符串。 Python中的字符串没有名为strptime
的方法。这给我们带来了问题#2:TypeError
子句中捕获ValueError
或except
。但是,您收到的错误是AttributeError: 'str' object has no attribute 'strptime'
。这是因为您无法调用您想要存在的方法但不能。你的除外行可能应该是except ValueError:
。except
子句没有任何用处(超出上面列出的问题)。如果字符串格式不正确,则打印消息但仍然继续。您可能希望在raise
子句中使用except
来进一步传播该异常。幸运的是,你真的希望日期成为一个字符串,这将我们带到问题#4:datetime.strptime
并且不要替换原始字符串;如果它没有正确转换,只会引发错误。else
),for
循环中的break
子句就会执行。由于您总是遍历所有行,因此您将始终触发else
子句。您需要有另一种方法来确定是否找到了匹配项,例如布尔标志或计数器。我将展示一个带计数器的例子,因为它更通用。with
块而不是原始open
。结合所有这些,您可以使代码看起来像这样:
def search_projection_date():
counter = 0
with open('projections.txt','r') as projections:
date = input("Input projection date: ")
for line in projections:
projection = line.strip("\n").split("|")
if date == projection[2]:
table = [['Code:',projection[0]],
['Hall:',projection[1]],
['Date:',projection[2]],
['Start time:',projection[3]],
['End time:', projection[4]],
['Day(s):', projection[5]],
['Movie:', projection[6]],
['Price:', projection[7]]]
print(tabulate(table))
counter += 1
if not counter:
print("No projection on that date")
else:
print("Found {0} projections on {1}".format(counter, date))
我信任您对tabulate
的使用,因为我不熟悉该模块,并且无意安装它。请注意,日期验证是可选的。如果用户输入了无效的字符串,那就是结束:您不需要检查'aaaa'
之类的日期,因为他们只会打印No projection on that date
。如果您坚持要保留验证,请执行以下操作:
from datetime import datetime
datetime.strftime(date, '%d.%m.%Y.')
那就是它。如果日期不匹配,它将引发ValueError
。你不需要对结果做任何事情。如果要更改错误消息,或者返回而不是引发错误,则可以捕获异常:
try:
datetime.strftime(date, '%d.%m.%Y.')
except ValueError:
print('Bad date entered')
return
请注意,我在这里捕获一种非常特殊的异常类型,而不是使用泛型except
子句。