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

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

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

Which types of objects fall into the domain of “subscriptable”?


回答 0

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

It basically means that the object implements the __getitem__() method. In other words, it describes objects that are “containers”, meaning they contain other objects. This includes strings, lists, tuples, and dictionaries.


回答 1

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

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__

Off the top of my head, the following are the only built-ins that are subscriptable:

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

But mipadi’s answer is correct – any class that implements __getitem__ is subscriptable


回答 2

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

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

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

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

A scriptable object is an object that records the operations done to it and it can store them as a “script” which can be replayed.

For example, see: Application Scripting Framework

Now, if Alistair didn’t know what he asked and really meant “subscriptable” objects (as edited by others), then (as mipadi also answered) this is the correct one:

A subscriptable object is any object that implements the __getitem__ special method (think lists, dictionaries).


回答 3

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

现在,在@ 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”对象不可下标

The meaning of subscript in computing is: “a symbol (notionally written as a subscript but in practice usually not) used in a program, alone or with others, to specify one of the elements of an array.”

Now, in the simple example given by @user2194711 we can see that the appending element is not able to be a part of the list because of two reasons:-

1) We are not really calling the method append; because it needs () to call it.

2) The error is indicating that the function or method is not subscriptable; means they are not indexable like a list or sequence.

Now see this:-

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

That means there are no subscripts or say elements in function like they occur in sequences; and we cannot access them like we do, with the help of [].

Also; as mipadi said in his answer; It basically means that the object implements the __getitem__() method. (if it is subscriptable). Thus the error produced:

arr.append["HI"]

TypeError: ‘builtin_function_or_method’ object is not subscriptable


回答 4

我有同样的问题。我在做

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

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

I had this same issue. I was doing

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

So using [ was causing error. It should be arr.append("HI")


回答 5

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

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

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)进行捕获。)

As a corollary to the earlier answers here, very often this is a sign that you think you have a list (or dict, or other subscriptable object) when you do not.

For example, let’s say you have a function which should return a list;

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

Now when you call that function, and something_happens() for some reason does not return a True value, what happens? The if fails, and so you fall through; gimme_things doesn’t explicitly return anything — so then in fact, it will implicitly return None. Then this code:

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

will fail with “NoneType object is not subscriptable” because, well, things is None and so you are trying to do None[0] which doesn’t make sense because … what the error message says.

There are two ways to fix this bug in your code — the first is to avoid the error by checking that things is in fact valid before attempting to use it;

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

or equivalently trap the TypeError exception;

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

Another is to redesign gimme_things so that you make sure it always returns a list. In this case, that’s probably the simpler design because it means if there are many places where you have a similar bug, they can be kept simple and idiomatic.

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 []

Of course, what you put in the else: branch depends on your use case. Perhaps you should raise an exception when something_happens() fails, to make it more obvious and explicit where something actually went wrong? Adding exceptions to your own code is an important way to let yourself know exactly what’s up when something fails!

(Notice also how this latter fix still doesn’t completely fix the bug — it prevents you from attempting to subscript None but things[0] is still an IndexError when things is an empty list. If you have a try you can do except (TypeError, IndexError) to trap it, too.)