Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean if a Python object is "subscriptable" or not?

Which types of objects fall into the domain of "subscriptable"?

like image 580
Alistair Avatar asked Oct 19 '08 21:10

Alistair


People also ask

What does it mean if an object is not Subscriptable Python?

Python throws the TypeError object is not subscriptable if you use indexing with the square bracket notation on an object that is not indexable. This is the case if the object doesn't define the __getitem__() method. You can fix it by removing the indexing call or defining the __getitem__ method.

What does it mean to be Subscriptable in Python?

What is Subscriptable in Python? “Subscriptable” means that you're trying to access an element of the object. The elements are usually accessed using indexing since it is the same as a mathematical notation that uses actual subscripts.

How do you fix the function object is not Subscriptable?

The error “TypeError: 'function' object is not subscriptable” occurs when you try to access an item from a function. Functions cannot be indexed using square brackets. To solve this error, ensure functions have different names to variables. Always call a function before attempting to access the functions.

What do you mean by type object is not Subscriptable?

All types are objects in Python. Thus you are actually trying to index into the type object. This is why the error message says that the "'type' object is not subscriptable."


Video Answer


6 Answers

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.

like image 108
mipadi Avatar answered Oct 05 '22 01:10

mipadi


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

like image 45
Dan Avatar answered Oct 05 '22 02:10

Dan


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

like image 38
tzot Avatar answered Oct 05 '22 02:10

tzot


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

like image 39
Vicrobot Avatar answered Oct 05 '22 02:10

Vicrobot


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

like image 21
tripleee Avatar answered Oct 05 '22 03:10

tripleee


I had this same issue. I was doing

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

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

like image 28
user2194711 Avatar answered Oct 05 '22 01:10

user2194711