Why can't I use a dictionary named `dict` before assigning to it?
Question:
I have multiple files that I need to load so I’m using a dict
to shorten things. When I run I get a
TypeError: 'type' object is not subscriptable
Error. How can I get this to work?
m1 = pygame.image.load(dict[1])
m2 = pygame.image.load(dict[2])
m3 = pygame.image.load(dict[3])
dict = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
playerxy = (375,130)
window.blit(m1, (playerxy))
Answers:
Normally Python throws NameError
if the variable is not defined:
>>> d[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
However, you’ve managed to stumble upon a name that already exists in Python.
Because dict
is the name of a built-in type in Python you are seeing what appears to be a strange error message, but in reality it is not.
The type of dict
is a type
. 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.”
>>> type(dict)
<type 'type'>
>>> dict[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'type' object is not subscriptable
Note that you can blindly assign to the dict
name, but you really don’t want to do that. It’s just going to cause you problems later.
>>> dict = {1:'a'}
>>> type(dict)
<class 'dict'>
>>> dict[1]
'a'
The true source of the problem is that you must assign variables prior to trying to use them. If you simply reorder the statements of your question, it will almost certainly work:
d = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
m1 = pygame.image.load(d[1])
m2 = pygame.image.load(d[2])
m3 = pygame.image.load(d[3])
playerxy = (375,130)
window.blit(m1, (playerxy))
you should update to python >= 3.9
and everything will work well
When I stumbled across this error, I had this function:
def trainByDistribution(xs: pd.DataFrame, ys: pd.DataFrame, step) -> tuple[float]:
My idea was to create a function that takes two pandas dataframes and an integer and would return a tuple of floating-pointing numbers.
Like other answers have stated, in Python everything is objects, even classes themselves. Classes are in turn blueprint objects that can be used to generate new objects, and consequently classes can be assigned to variables, passed as arguments and programmatically constructed with type()
function.
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return str(name) + str(age)
This class is equivalent to this:
def __init__(self, name, age):
self.age = age
self.name = name
def __str__(self):
return str(name) + str(age)
Person = type("Person, ("object",), {"__init__": __init__,
"__str__": __str__})
This error "object is not subscriptable" appears when you pass to a function an object that doesn’t support accessing values by indexing (doesn’t overload the [] operator). Since the type of all classes is <class "type">
:
>>> type(Person)
<class "type">
then type object is not subscriptable means you pass class instead of an actual object. This could be more tricky though, in my function above I passed valid dataframes, and my error appeared because I attempted to annotate the return type as tuple[float]
, and while this syntax should be legal to my knowledge, the interpreter understood this expression as if I wanted to index the tuple class itself.
Conclusions
This error appears when:
- you pass class instead of an actual object to a function argument;
- you use the class name to index anything, including naming variables with class names.
You can take a look at this tutorial by mCoding to find out more about classes as objects.
For me I go the same error once I try to access model class attributes like if it was dictionary dimension['dimension_id']
though dimension type is
app.models.evaluation.DimensionsEvaluation object
so I got the error
TypeError: 'DimensionsEvaluation' object is not subscriptable
to fix this I had to get the dictionary field from the model class using .__dict__
and access my attribute normally like above:
...
for dimension in evaluation_dimensions:
print(f"n dimension_id: {dimension['dimension_id']}n") #TypeError: 'DimensionsEvaluation' object is not subscriptable
for dimension in evaluation_dimensions:
dimension_dic = dimension.__dict__
print(f"n dimension_id: {dimension_dic['dimension_id']}n") #dimension_id: 1
...
I have multiple files that I need to load so I’m using a dict
to shorten things. When I run I get a
TypeError: 'type' object is not subscriptable
Error. How can I get this to work?
m1 = pygame.image.load(dict[1])
m2 = pygame.image.load(dict[2])
m3 = pygame.image.load(dict[3])
dict = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
playerxy = (375,130)
window.blit(m1, (playerxy))
Normally Python throws NameError
if the variable is not defined:
>>> d[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined
However, you’ve managed to stumble upon a name that already exists in Python.
Because dict
is the name of a built-in type in Python you are seeing what appears to be a strange error message, but in reality it is not.
The type of dict
is a type
. 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.”
>>> type(dict)
<type 'type'>
>>> dict[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'type' object is not subscriptable
Note that you can blindly assign to the dict
name, but you really don’t want to do that. It’s just going to cause you problems later.
>>> dict = {1:'a'}
>>> type(dict)
<class 'dict'>
>>> dict[1]
'a'
The true source of the problem is that you must assign variables prior to trying to use them. If you simply reorder the statements of your question, it will almost certainly work:
d = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
m1 = pygame.image.load(d[1])
m2 = pygame.image.load(d[2])
m3 = pygame.image.load(d[3])
playerxy = (375,130)
window.blit(m1, (playerxy))
you should update to python >= 3.9
and everything will work well
When I stumbled across this error, I had this function:
def trainByDistribution(xs: pd.DataFrame, ys: pd.DataFrame, step) -> tuple[float]:
My idea was to create a function that takes two pandas dataframes and an integer and would return a tuple of floating-pointing numbers.
Like other answers have stated, in Python everything is objects, even classes themselves. Classes are in turn blueprint objects that can be used to generate new objects, and consequently classes can be assigned to variables, passed as arguments and programmatically constructed with type()
function.
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return str(name) + str(age)
This class is equivalent to this:
def __init__(self, name, age):
self.age = age
self.name = name
def __str__(self):
return str(name) + str(age)
Person = type("Person, ("object",), {"__init__": __init__,
"__str__": __str__})
This error "object is not subscriptable" appears when you pass to a function an object that doesn’t support accessing values by indexing (doesn’t overload the [] operator). Since the type of all classes is <class "type">
:
>>> type(Person)
<class "type">
then type object is not subscriptable means you pass class instead of an actual object. This could be more tricky though, in my function above I passed valid dataframes, and my error appeared because I attempted to annotate the return type as tuple[float]
, and while this syntax should be legal to my knowledge, the interpreter understood this expression as if I wanted to index the tuple class itself.
Conclusions
This error appears when:
- you pass class instead of an actual object to a function argument;
- you use the class name to index anything, including naming variables with class names.
You can take a look at this tutorial by mCoding to find out more about classes as objects.
For me I go the same error once I try to access model class attributes like if it was dictionary dimension['dimension_id']
though dimension type is
app.models.evaluation.DimensionsEvaluation object
so I got the error
TypeError: 'DimensionsEvaluation' object is not subscriptable
to fix this I had to get the dictionary field from the model class using .__dict__
and access my attribute normally like above:
...
for dimension in evaluation_dimensions:
print(f"n dimension_id: {dimension['dimension_id']}n") #TypeError: 'DimensionsEvaluation' object is not subscriptable
for dimension in evaluation_dimensions:
dimension_dic = dimension.__dict__
print(f"n dimension_id: {dimension_dic['dimension_id']}n") #dimension_id: 1
...