python - 如何同时捕获 OSError 和 FileNotFoundError
问题描述
在我正在处理的代码中,当用户输入文件名以从中加载数据或将数据保存到时,我发现了一些异常。我想要的是在 Windows 上的文件名无效(例如“///”)和请求的文件不存在的情况下显示不同的消息。
问题:如果我尝试在OSError
输入无效文件名时捕获触发它会覆盖FileNotFoundError
例如:
filename = input('Please enter filename containing data: ')
try:
data = load_data(filename)
except OSError:
print('Invalid file name. Try again.')
except FileNotFoundError:
print('File does not exist. Please try again.')
except TypeError:
print('Please enter a valid file name.')
except json.decoder.JSONDecodeError:
print('Invalid file format.')
在这里,如果我输入了一个无效的文件名,例如,///
或者一个不存在的文件名 - 在这两种情况下都会OSError
触发。另一方面,JSONDecodeError
被正确捕获。
我尝试过切换OSError
,FileNotFoundError
但仍然只有OSError
曾经的触发器。只有当我完全删除 OSError 时,我才能真正捕获 FNFError。
任何人都知道我怎样才能分别捕获OSError
两者FNFError
?
编辑:当我切换 except 语句的顺序时会发生这种情况:
filename = input('Please enter filename containing data: ')
try:
data = load_data(filename)
except FileNotFoundError:
print('File does not exist. Please try again.')
except OSError:
print('Invalid file name. Try again.')
except TypeError:
print('Please enter a valid file name.')
except json.decoder.JSONDecodeError:
print('Invalid file format.')
>>> Please enter filename containing data: ///
Out: File does not exist. Please try again.
编辑2:
这是代码load_data()
:
def load_data(filename: str) -> dict:
with open(filename, 'r') as jsfile:
data = json.load(jsfile)
print(f'\nLoaded {len(data.keys())} records.')
return data
解决方案
只需更改顺序(FileNotFoundError
是的子类OSError
)¯\_(ツ)_/¯
因为→</p>
for f in ["///", "blahblah"]:
try:
open(f, "rb")
except FileNotFoundError:
print('File does not exist: '+f+'. Please try again.')
except OSError:
print('Invalid file name: '+f+'. Try again.')
except TypeError:
print('Please enter a valid file name: '+f+'.')
except json.decoder.JSONDecodeError:
print('Invalid file format: '+f+'.')
Invalid file name: ///. Try again.
File does not exist: blahblah. Please try again.
但:
for f in ["///", "blahblah"]:
try:
open(f, "rb")
except OSError:
print('Invalid file name: '+f+'. Try again.')
except FileNotFoundError:
print('File does not exist: '+f+'. Please try again.')
except TypeError:
print('Please enter a valid file name: '+f+'.')
except json.decoder.JSONDecodeError:
print('Invalid file format: '+f+'.')
Invalid file name: ///. Try again.
Invalid file name: blahblah. Try again.
测试Python 3.7.1
于Linux
编辑 1。
使用 json.load() 测试的行为
按预期工作 →</p>
import json
for f in ["///", "blahblah"]:
try:
with open(f, 'r') as jsfile:
data = json.load(jsfile)
except FileNotFoundError:
print('File does not exist: '+f+'. Please try again.')
except OSError:
print('Invalid file name: '+f+'. Try again.')
except TypeError:
print('Please enter a valid file name: '+f+'.')
Invalid file name: ///. Try again.
File does not exist: blahblah. Please try again.
你在使用 Windows 吗?不确定///
Windows FS (NTFS) 的名称是否错误。例如\\\
是 Linux FS 的好名字
import json
for f in ["\\\\\\", "///", "blahblah"]:
try:
with open(f, 'r') as jsfile:
data = json.load(jsfile)
except FileNotFoundError:
print('File does not exist: '+f+'. Please try again.')
except OSError:
print('Invalid file name: '+f+'. Try again.')
except TypeError:
print('Please enter a valid file name: '+f+'.')
File does not exist: \\\. Please try again.
Invalid file name: ///. Try again.
File does not exist: blahblah. Please try again.
$ touch '\\\'
$ ls -l
...
-rw-r--r--. 1 root root 0 May 25 11:59 \\\
...
推荐阅读
- javascript - 使用 javascript 和 jQuery 在 MySql 中将值从一个表插入到另一个表
- multipartform-data - Mule 4:HTTP 请求者:如何将 multipart/form-data 作为 Mule REST 服务调用的 POST 正文发送?
- sql - 如何在redshift Postgresql中使用字符串作为列名(字符串到列名的动态转换)
- javascript - d3-xyzoom:与 webpack 一起使用时,滚动(滚轮)缩放抛出“d3-xyzoom.js:83 Uncaught TypeError: Cannot read property 'button' of null”
- ruby - 将一个范围的每个项目分配给哈希中另一个范围的每个项目
- javascript - 单击选择/选项时的 JavaScript 新选项卡
- angular - 为什么 flushMicrotasks() 和 tick() 在 fakeAsync 中不执行 setImmediate 回调?
- django - Django 密码显示在表单数据(发布/请求)中
- python - 定位 ID 的最小值和最大值的数据框列
- apache-spark - 将每个 spark 数据框元素与同一数据框的所有其余部分进行比较