File-like objects是Python中的对象,其行为类似于一个真实的文件,例如具有read()和write方法(),但具有不同的实现。它是Duck Typing概念的实现。
在需要文件的地方允许类似文件的对象出现在任何地方,这样就可以使用StringIO或Socket对象来代替真正的文件,这被认为是一种良好的实践。所以这样的检查是不好的:
if not isinstance(fp, file):
raise something
检查对象(例如方法的参数)是否“类似文件”的最佳方法是什么?
Tags:
对于3.1+,请执行以下操作之一:
对于2.x来说,“类似文件的对象”是一个很模糊的东西,无法检查,但是您正在处理的任何函数的文档都可能告诉您它们实际需要什么;如果没有,请阅读代码。
正如其他答案所指出的,首先要问的是你到底在查什么。通常,EAFP是足够的,而且更习惯。
The glossary说“类文件对象”是“文件对象”的同义词,这最终意味着它是the ^{} module 中定义的三个abstract base classes中的一个实例,它们本身都是
IOBase
的子类。所以,检查的方法正是上面所示的。(但是,检查
IOBase
不是很有用。你能想象这样一种情况吗:你需要把一个像read(size)
这样的实际文件与一个名为read
的不象文件的参数函数区分开来,而不需要区分文本文件和原始二进制文件?所以,实际上,您几乎总是想检查,例如,“是文本文件对象”,而不是“是类似文件的对象”。)对于2.x,虽然
io
模块自2.6+以来就已经存在,但内置文件对象不是io
类的实例,stdlib中也不是任何类似文件的对象,也不是您可能遇到的大多数类似第三方文件的对象。“类文件对象”的含义没有官方定义;它只是“类似于内置的file object”,不同的函数用“类”表示不同的东西。这些函数应该记录它们的含义;如果它们没有,则必须查看代码。但是,最常见的含义是“has
read(size)
”、“hasread()
”或“is a iterable of strings”,但是一些旧库可能期望readline
而不是其中之一,有些库喜欢您给它们的close()
文件,有些库希望如果fileno
存在,则可以使用其他功能,等等,对于write(buf)
也同样如此(尽管在这个方向上有更少的选择)。正如其他人所说,你一般应该避免这样的检查。一个例外是,对象可能是合法的不同类型,并且您希望根据类型有不同的行为。EAFP方法并不总是在这里工作,因为一个对象可能看起来像不止一种类型的duck!
例如,初始化程序可以获取自己类的文件、字符串或实例。然后您可能会得到如下代码:
在这里使用EAFP可能会导致各种微妙的问题,因为在抛出异常之前,每个初始化路径都会部分运行。 从本质上说,这种构造模仿函数重载,因此不是很Python,但如果小心使用,它可能会很有用。
顺便说一句,在Python 3中,不能用同样的方法检查文件。你需要像
isinstance(f, io.IOBase)
这样的东西。除非有特殊要求,否则在代码中进行这种检查通常是不好的。
在Python中,输入是动态的,为什么需要检查对象是否像文件一样,而不是像文件一样使用它并处理结果错误?
无论如何,您可以执行的任何检查都将在运行时进行,因此执行类似于
if not hasattr(fp, 'read')
的操作并引发一些异常,所提供的实用性不会比仅调用fp.read()
和在方法不存在时处理结果属性错误多多少。相关问题 更多 >
编程相关推荐