检查 [] 操作符
我想知道在Python中,怎么检查一个对象是否支持使用方括号([])这个操作?我想到的方式大概是这样的:
if supports(obj, ?[]?):
print("Supports")
5 个回答
3
在编程中,方括号 []
的内部名称叫做 __getitem__
(还有 __setitem__
)。这意味着你可以用这些名字来做一些操作,下面的代码可以帮助你理解:
if hasattr(obj, '__getitem__'):
print "Supports"
15
你不需要“检查支持”。你只需要直接使用它:
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 原则,那就是“请求原谅总比请求许可更容易”。
这个语言就是为了通过异常处理来实现这一点的。
12
试试 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].
可以查看 operator模块:
返回在索引 b 处的 a 的值:
operator.getitem(a, b) operator.__getitem__(a, b)
返回从索引 b 到索引 c-1 的 a 的切片:
operator.getslice(a, b, c) operator.__getslice__(a, b, c)
将索引 b 处的 a 的值设置为 c:
operator.setitem(a, b, c) operator.__setitem__(a, b, c)
将从索引 b 到索引 c-1 的 a 的切片设置为序列 v。
operator.setslice(a, b, c, v) operator.__setslice__(a, b, c, v)
移除索引 b 处的 a 的值:
operator.delitem(a, b) operator.__delitem__(a, b)
删除从索引 b 到索引 c-1 的 a 的切片:
operator.delslice(a, b, c) operator.__delslice__(a, b, c)
等等……