Python 3:确定对象是否支持IO

时间:2011-05-02 13:49:41

标签: python interface python-3.x

某些Python方法适用于各种输入源。例如,XML元素树parse方法接受一个对象,该对象可以是字符串(在这种情况下,API将其视为文件名),或者是支持IO接口的对象,如文件对象或io.StringIO

因此,显然parse方法正在进行某种界面嗅探,以确定要采取的行动方案。我想最简单的方法是通过说isinstance(x, str)检查输入参数是否为字符串,如果是,则将其视为文件名,否则将其视为IO对象。

但是为了更好的错误检查,我认为最好检查x是否支持IO接口。检查对象是否支持指定接口的标准惯用方法是什么?

我想,有一种方法就是说:

if "read" in x.__class__.__dict__: # check if object has a read method

但仅仅因为x具有“读取”方法并不一定意味着它支持IO接口,所以我假设我还应该检查IO接口中的每个方法。这通常是最好的方法吗?或者我应该忘记检查界面,只是让一个可能的AttributeError进一步处理堆栈?

3 个答案:

答案 0 :(得分:3)

Python强烈鼓励使用duck:只是假设传入的对象有效并尝试使用它。这样,您的代码尽可能灵活。当然,如果代码的操作依赖于传入的对象的类型,则需要进行某种类型检查。我建议尽量减少此类型检查,并转到isinstance(x, str)

如果传入既不是字符串也不支持IO接口的对象,则会产生AttributeError。如果发生这种情况,这是调用代码中的错误。不应该在任何地方处理此异常 - 而应该修复错误!

那就是说,你可以使用

isinstance(x, io.IOBase)

测试支持I / O协议的内置类。这会将您的代码限制为实际派生自io.IOBase的类 - 这是一种肤浅且不必要的限制。

答案 1 :(得分:1)

  

或者我应该忘记检查界面,只是让可能的AttributeError进一步处理堆栈?

一般的pythonic原理似乎是在做你想要做的任何事情,并且只捕获它可能导致的任何异常。这就是所谓的 duck typing 。但这并不一定意味着您应该让这些异常从您的函数转移到调用代码。如果能够以有意义的方式这样做,你可以在函数本身中处理它们。

答案 2 :(得分:0)

是的,python是关于鸭子打字的,并且检查一些方法来确定一个对象是否支持IO接口是完全可以接受的。有时,尝试在try / except块中调用方法并捕获TypeErrorValueError甚至是有意义的,因此您知道真的是否支持相同的接口(但是使用这节俭节俭)。我会说使用hasattr而不是查看__class__.__dict__,否则这就是我要采取的方法。

(一般情况下,我首先检查标准库中是否有某个方法来处理这样的事情,因为它很容易自行决定什么构成“IO接口”。例如,typesinspect模块中有一些方便的宝石用于相关的接口检查。)