如何在Python中检查对象是否支持[]操作?我想到类似以下内容:
if supports(obj, ?[]?):
print("Supports")
答案 0 :(得分:14)
您没有“检查支持”。你只需使用它:
try:
a = obj[whatever]
except TypeError:
# whatever your fall-back plan is when obj doesn't support [] (__getitem__)
编写自己的isinstance
总是错误的。不从集合ABC类继承的新类型仍然可以具有正确的行为。 Duck Typing意味着你永远不能依赖isinstance
。
编写自己的hasattr
测试只会复制Python引发异常的内部检查。由于Python 必须进行测试,为什么要复制呢?
最后,“我认为通过异常处理,这段代码的可读性会降低。”是假的。许多经验丰富的Python程序员都接受的Pythonic原则是,要求宽恕更容易获得许可。
该语言旨在通过例外来实现此目的。
答案 1 :(得分:5)
尝试hasattr(obj, "__getitem__")
:
if hasattr(obj, "__getitem__"):
print("Supports")
来自operator.getitem
帮助:
operator.getitem??
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
String Form: <built-in function getitem>
Namespace: Interactive
getitem(a, b) -- Same as a[b].
返回索引b的值:
operator.getitem(a, b) operator.__getitem__(a, b)
将索引b的切片返回到索引c-1:
operator.getslice(a, b, c) operator.__getslice__(a, b, c)
将索引b的值设置为c:
operator.setitem(a, b, c) operator.__setitem__(a, b, c)
将索引b的切片设置为索引c-1到序列v。
operator.setslice(a, b, c, v) operator.__setslice__(a, b, c, v)
删除索引b的值:
operator.delitem(a, b) operator.__delitem__(a, b)
将索引b的切片删除为索引c-1:
operator.delslice(a, b, c) operator.__delslice__(a, b, c)
等。
答案 2 :(得分:3)
[]
运算符的内部名称为__getitem__
(以及__setitem__
),因此您可以通过以下方式进行相当好的尝试:
if hasattr(obj, '__getitem__'):
print "Supports"
答案 3 :(得分:2)
根据language docs,您可以检查班级是否有__getitem__
方法。
答案 4 :(得分:2)
有一种简单的方法可以查看是否可以迭代一个对象(即执行for i in obj
):
import collections
if isinstance(obj, collections.Iterable):
print 'obj supports iteration'
如果您担心检查是否可以使用实际密钥,我建议只是“请求原谅”而不是许可:
try:
value = obj[key]
except (AttributeError, TypeError, IndexError):
# These are different things that can return in different situations
value = None
print 'I guess that key doesn\'t work'
我建议使用collections.Iterable
代替此方法的唯一原因是,围绕try
循环的for
知道还有什么,可能会变得复杂。