Python对象是否“可订阅”是什么意思?


Answers:


356

它基本上意味着对象实现了该__getitem__()方法。换句话说,它描述的是“容器”对象,这意味着它们包含其他对象。这包括字符串,列表,元组和字典。


2
hasattr(SomeClassWithoutGetItem, '__getitem__')确定一个事物是否可以下标的可靠性如何?
jmunsch

2
[... ]索引语法被称为下标,因为它等同于数学符号使用实际标; 例如a[1]Python是数学家写成a₁的东西。因此,“可下标”是指“可以下标”。用Python来说,这意味着它必须实现__getitem__(),因为a[1]它只是的语法糖a.__getitem__(1)
Mark Reed

的调用hasattr应该可以正常工作,但这不是Python的处理方式。Python实践鼓励Duck Typing。意思是,如果您打算尝试使用下标从对象中获取项目,请继续进行;如果您认为该对象可能无法下标而无法正常工作,请使用将该对象包装在一个 try块中except TypeError
Mark Reed

77

在我脑海中,以下是唯一可以下标的内置程序:

string:  "foobar"[3] == "b"
tuple:   (1,2,3,4)[3] == 4
list:    [1,2,3,4][3] == 4
dict:    {"a":1, "b":2, "c":3}["c"] == 3

但是mipadi的答案是正确的-实现的任何类都可以下__getitem__


17

可编写脚本的对象是记录对其执行的操作的对象,并且可以将它们存储为“脚本”并可以重播。

例如,请参见:应用程序脚本框架

现在,如果Alistair不知道他问的是什么(真正由他人编辑的)“可订阅的”对象,那么(正如mipadi也回答的那样),这是正确的:

下标对象是实现__getitem__特殊方法的任何对象(例如列表,字典)。


2
请注意,我是在回答有关“可编写脚本”的对象的原始问题,而不是其他人(不是Alistair)编辑的“可编写下标的”对象。我真的希望Alistair发表评论。
tzot

啊,这是我收藏的新徽章!:)显然是在开玩笑。唯一可以证明问题编辑的理由是,阿利斯泰尔选择了答案。我仍然不确定Alistair是否确定选择。
tzot

16

下标在计算中的含义是:“在程序中单独或与其他一起使用的符号(名义上写为下标,但实际上通常不使用)来指定数组的元素之一。”

现在,在@ user2194711给出的简单示例中,我们可以看到,由于两个原因,appending元素不能成为列表的一部分:

1)我们并不是真正地将方法称为append;因为它需要()调用它。

2)错误表明该函数或方法不可下标;表示它们不可像列表或序列那样进行索引。

现在看到这个:

>>> var = "myString"
>>> def foo(): return 0
... 
>>> var[3]
't'
>>> foo[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'function' object is not subscriptable

这意味着没有下标或说元素function按顺序出现。并且我们无法在的帮助下访问它们[]

也; 正如米帕迪在回答中所说的;它基本上意味着对象实现了该__getitem__()方法。(如果可以下标)。因此产生了错误:

arr.append["HI"]

TypeError:“ builtin_function_or_method”对象不可下标


7

我有同样的问题。我在做

arr = []
arr.append["HI"]

因此,使用[会导致错误。它应该是arr.append("HI")


3

作为此处较早答案的推论,通常这表示您认为没有列表(或字典或其他可下标对象)的列表。

例如,假设您有一个返回列表的函数。

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']

现在,当您调用该函数并且something_happens()由于某种原因未返回True值时,会发生什么?的if失败,这样你就告吹; gimme_things不会明确显示return任何内容-因此实际上,它会隐式地显示return None。然后这段代码:

things = gimme_things()
print("My first thing is {0}".format(things[0]))

会失败,并显示“ NoneType对象不可下标”,因为,thingsNone,所以您正在尝试这样做None[0]是没有意义的,因为...错误消息说了什么。

有两种方法可以在代码中修复此错误-第一种方法是通过things在尝试使用该错误之前检查其是否有效来避免该错误;

things = gimme_things()
if things:
    print("My first thing is {0}".format(things[0]))
else:
    print("No things")  # or raise an error, or do nothing, or ...

或等效地捕获TypeError异常;

things = gimme_things()
try:
    print("My first thing is {0}".format(things[0]))
except TypeError:
    print("No things")  # or raise an error, or do nothing, or ...

另一个是重新设计gimme_things,以确保您始终返回列表。在这种情况下,这可能是更简单的设计,因为这意味着,如果在很多地方存在类似的错误,可以将它们保持简单且惯用。

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']
    else:  # make sure we always return a list, no matter what!
        logging.info("Something didn't happen; return empty list")
        return []

当然,放在else:分支中的内容取决于您的用例。也许您应该在something_happens()失败时引发异常,以使其更明显,更明确地指出实际出问题的地方?将异常添加到自己的代码中是一种重要的方式,可以让您自己确切地知道发生故障时发生了什么!

(还请注意,后一个修复程序仍无法完全解决该错误-它阻止您尝试下标,Nonethings[0]仍然是IndexErrorwhen things是空列表。如果有,try也可以except (TypeError, IndexError)进行捕获。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.