Attribute Error: object has no attribute
Attribute Error: object has no attribute
.There is no such attribute
If the Python object does not have an attribute with the requested name, we will receive an AttributeError
.
We can check the list of existing attributes using dir(object)
.
obj = "Python" # list of atributes print(dir(obj))
Expecting for another object
We may mistakenly expect an object of a different type as a result of some operations.
For example, a package has different functions or class methods that return data in various forms.
import package result = package.foo() # we are trying to use the list method on a generator object result.append(4) # AttributeError: 'generator' object has no attribute 'append'
In this particular case, we can first convert the result to a list.
A similar error may occur when using method chaining. Using method chaining in tkinter, tk.Entry().pack()
, results in a non-obvious error. The pack, grid, and place return None
.
import tkinter as tk root = tk.Tk() field = tk.Entry() # Entry object field.pack() field1 = tk.Entry().pack() # return None print(field, type(field)) # .!entry <class 'tkinter.Entry'> print(field1, type(field1)) # None <class 'NoneType'> field1.get() # AttributeError: 'NoneType' object has no attribute 'get'
Some functions are designed to return different results depending on the circumstances. For example, dict.get()
returns None
if the key is not found in the dictionary.
d = { "id1": {"a": "A"} } result = d.get("id1") print(result.keys()) # dict_keys(['a']) result = d.get("id2") # there is no such key print(result.keys()) # AttributeError: 'NoneType' object has no attribute 'keys'
API changes
While using some Python packages, we may encounter AttributeError
due to API changes. Every major version update contains breaking changes. Some functions or classes may be deprecated and removed in a new version. Or vice versa, we are trying to use new functionality that is not available in older versions. Make sure you have the appropriate version of the package installed.
In this case, we may get an error for the module.
import modulename # attempting to access an attribute modulename.attrname # AttributeError: module 'modulename' has no attribute 'attrname'
Standard modules may also differ in different versions of Python.
Reassigned names and Name collision.
Python allows you to reuse names, including the names of built-in functions and PSL modules. The same things can happen when we use PyPI packages.
import keyword # reassigning the name "keyword" to a string object keyword = "Python" # attempting to get the module attribute print(keyword.kwlist) # AttributeError: 'str' object has no attribute 'kwlist'
If we define some variables, functions, or classes in our code, we need to make sure that their names are unique in the current namespace.
Name collisions can occur when using wildcard import. For example, if the imported modules have classes with the same names but different attributes. Depending on the order in which the modules are imported, we will get different objects.
from tkinter import * from tkinter.ttk import * print(Button) # <class 'tkinter.ttk.Button'>
from tkinter.ttk import * from tkinter import * print(Button) # <class 'tkinter.Button'>
A variation of the naming confusion can occur when we name files with our code the same as named standard library modules or third-party packages.
Wrong object
We are using the wrong object to access the attribute. For example, we are trying to access an instance attribute through a class.
class A: def __init__(self, value): self.value = value a = A(12) print(a.value) # 12 print(A.value) # AttributeError: type object 'A' has no attribute 'value'
Typo in __init__
Due to the incorrect spelling, _init_
is not a special method but a regular class method. It is not called when an instance is created, so self attributes are not created either.
class A: def _init_(self): self.data = [] def method(self, num): self.data.append(num) a = A() a.method(1) # AttributeError: 'A' object has no attribute 'data' print(a.data) # AttributeError: 'A' object has no attribute 'data'
Deleted or changed attribute
User-defined functions, classes, and class instances allow you to add, modify, and remove arbitrary attributes on the fly.
class A: attr = 1 print(A.attr) # 1 del A.attr print(A.attr) # AttributeError: type object 'A' has no attribute 'attr'
Attributes of a built-in type
Manipulation of attributes of Python built-in types is limited. Setting an attribute on an instance of a built-in type will result in an error.
obj = [1, 2] obj.attr = 12 # AttributeError: 'list' object has no attribute 'attr' print.attr = 1 # AttributeError: 'builtin_function_or_method' object has no attribute 'attr'
Access to attributes is restricted
Classes can restrict access to their attributes. We can define public and "private" attributes of an object.
There is a convention that a name prefixed with an underscore (a variable or function name) should be considered a non-public part of the API. Names with two leading underscores are automatically renamed by prefixing their name with the class name and one leading underscore. This is known as name mangling.
class A: __private1 = 1 def __init__(self): self.__private2 = 2 a = A() print(dir(A)) # ['_A__private1', ...] print(dir(a)) # ['_A__private1', '_A__private2', ...] print(a.__private1) # AttributeError: 'A' object has no attribute '__private1'. Did you mean: '_A__private1'? print(a.__private2) # AttributeError: 'A' object has no attribute '__private2'. Did you mean: '_A__private2'? print(A.__private1) # AttributeError: type object 'A' has no attribute '__private1'. Did you mean: '_A__private1'?
If a class defines __slots__
, then it explicitly declares the allowed data attributes for instances.
class A: __slots__ = ("value",) def __init__(self, value): self.value = value a = A(1) print(a.value) # 1 a.value2 = 2 # AttributeError: 'A' object has no attribute 'value2'
Python also has options for customizing attribute lookups: __get__
, __set__
, __delete__
, __getattr__
, __getattribute__
, __setattr__
, __delattr__
, and @property
.
References: