哪些类型的对象属于“可订阅”的域?

#1 楼

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

评论


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

– jmunsch
19年11月22日在21:19

索引语法称为下标,因为它等效于使用实际下标的数学符号。例如a [1]是Python,数学家将其写为a₁。因此,“可下标”是指“可以下标”。用Python来讲,这意味着它必须实现__getitem __(),因为a [1]只是a .__ getitem __(1)的语法糖。

–马克·里德(Mark Reed)
4月2日14:15



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

–马克·里德(Mark Reed)
4月2日14:28



#2 楼

在我脑海中,下面是唯一可以下标的内置函数:

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__的类都可以下标

#3 楼

可编写脚本的对象是记录对其执行的操作的对象,并且可以将其存储为可以重播的“脚本”。例如,请参见:应用程序脚本框架

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

一个可订阅的对象object是实现__getitem__特殊方法的任何对象(请考虑列表,字典)。

评论


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

–tzot
08-10-19在22:24

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

–tzot
08-10-19在22:30

#4 楼

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

现在,在@ 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的帮助下像我们一样访问它们。

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

arr.append["HI"]



TypeError:'builtin_function_or_method'对象不可下标


#5 楼

我有同样的问题。我正在做

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


所以使用[会导致错误。应该是arr.append("HI")

#6 楼

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

例如,假设您有一个应返回列表的函数;现在,当您调用该函数时,由于某种原因,something_happens()不返回True值,会发生什么? if发生故障,因此您失败了; gimme_things不会明确显示任何内容-因此,实际上,它会隐式地显示return。然后,此代码:

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


将失败,并显示“ return None对象不可下标”,因为NoneTypethings,因此您尝试执行的操作不是这是有道理的,因为...错误消息说的是什么。

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

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


或等效地捕获None[0]异常;

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 ...


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

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 ...


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

(请注意,后一种修复仍无法完全解决该错误-它阻止您尝试为else:下标,但是当something_happens()为空列表时None仍然是things[0]。如果您有IndexError,也可以执行things对其进行陷印。)