python - 处理文件时如何正确处理错误?
问题描述
节目说明:
.txt
程序从第一个输入创建一个具有给定名称的文件。之后,它接受来自每个输入的文件的文本行,直到输入仅包含一个字符串"end"
(不应包含此结束行)。该程序还应该处理所有可能的错误。
我的解决方案:
def writef(f, st):
try:
assert st == "end", "* End of the file (not included)"
assert not(f.endswith(".txt")), "txt only"
except IOError:
print("Unexpected error")
except AssertionError as sterr:
print(sterr)
f.write(st + "\n")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
while True:
exec_st = input("> ")
writef(f, exec_st)
问题:
- 我的程序接受各种文件。我不知道如何处理将显示文件应该具有
.txt
扩展名的错误(正确显示 AssertionError 消息)。 AssertionError
在每个输入行之后,如果字符串仅包含"end"
: ,它还会输出消息* End of the file (not included)
。但是,当我尝试键入仅包含单词的字符串时,"end"
它会输出以下错误而不是 AssertionError:
Traceback (most recent call last):
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 15, in <module>
writef(f, exec_st)
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 4, in writef
assert not(f.endswith(".txt")), "txt only"
AttributeError: '_io.TextIOWrapper' object has no attribute 'endswith'
我将不胜感激,在此先感谢。
解决方案
断言语句的工作方式是当你说
assert st == "end", "* End of the file (not included)"
你是说你假设st
等于end
。如果由于某种原因这不是真的,请引发错误。使用!=
将使程序按照您的解释工作,但是,您甚至不应该在这里使用断言语句。断言语句仅用于完整性检查,它们在生产中被剥离。我的意思是大多数公司将以一种特殊的优化模式运行 Python,该模式会跳过断言语句。有关更多信息,请参阅此问题。而是引发如下错误:
if st == "end":
raise RuntimeError("* End of the file (not included)")
这将确保您的错误在应有的时候被提出,但我们仍然需要处理该'_io.TextIOWrapper' object has no attribute 'endswith'
错误。您正在检查是否f
不以“.txt”结尾。f
是open()
返回什么,如果您查找文档以查看该函数返回的内容,您会发现它不返回字符串,但该endswith
函数只能对字符串进行操作,因此会出现错误。你可以做的是传递t
给你的writef
函数并检查它是否以“txt”结尾,或者你可以像 PIG208 提到的那样做并检查是否f.name
以“.txt”结尾。
其他一些需要考虑的事情:
您应该养成使用更具描述性的名称的习惯。当您稍后回到您的代码时,它会为您提供帮助。我不知道代表什么
t
,st
将来你也不知道它们代表什么。您应该尽可能避免打印出“意外错误”,以支持更具体的错误消息。你只会因为不告诉他们发生了什么而惹恼他们,当你的用户抱怨这个非常笼统的错误消息时,你会惹恼自己。
您的 try catch 块围绕一些不做任何 IO 工作的断言语句,但无论如何您都会捕获 IO 错误。这是没有必要的。如果你得到一个 IO 错误,它将来自
f.write
oropen
或f.close
。
推荐阅读
- firebase-realtime-database - 如果我创建两三个数据库但使用在 spark 计划的限制范围内,那么 firebase Blaze 计划的成本是多少?
- node.js - ExpressJS Cors 问题:请求的资源上不存在“Access-Control-Allow-Origin”标头
- c++ - 在 std::set 中删除元素的正确方法
- ruby-on-rails - 试图将 api 数据保存到我的数据库中,@headline 没有被填充到表中
- ios - 有没有办法在 Interface Builder 中预加载 WKWebView?
- firebase - Xcode 10.2 编译问题 FirebaseCore
- java - String[].split(String regex) 在使用 String 作为正则表达式时根本不会拆分
- bash - 如何使局部变量从一个循环传递到另一个循环
- python - 当 Flask 中的 request.method == 'POST' 时,Redirect() 不起作用
- javascript - 为什么我的下一个按钮的代码循环播放幻灯片但上一个按钮不是?