检查 [] 操作符

9 投票
5 回答
3298 浏览
提问于 2025-04-17 03:23

我想知道在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)
    

等等……

撰写回答