Last updated: Apr 8, 2024
Reading timeยท4 min
The Python "AttributeError: partially initialized module has no attribute" occurs for two main reasons:
A
imports file B
and vice versa.requests.py
.Here is an example of how the error occurs in a file called requests.py
.
import requests def make_request(): # โ๏ธ AttributeError: partially initialized module 'requests' # has no attribute 'get' (most likely due to a circular import) res = requests.get('https://reqres.in/api/users') parsed = res.json() print(parsed) make_request()
Notice that I am importing the requests
third-party module in a local file
called requests.py
.
Having my local file named the same as the module I am importing is causing a circular import.
The Python interpreter first looks for the imported module in the built-in modules, then in the current directory, then in the PYTHON PATH, then in the installation-dependent default directory.
Make sure you haven't named your local modules with names of remote modules,
e.g. requests.py
or datetime.py
and remove any circular dependencies in
import statements.
A good way to start debugging is to print(dir(your_module))
and see what
attributes the imported module has.
import requests # ['__builtins__', '__cached__', '__doc__', '__file__', # '__loader__', '__name__', '__package__', '__spec__', 'requests'] print(dir(requests))
If we look at the attributes the imported requests
module has, we don't see
any of the actual methods the official requests
module provides.
This is a clear indication, that we are shadowing the third-party module with our local module.
This can also happen when you give a module the same name as a standard-library
module, e.g. datetime
.
You can use the sys
module to print all of the built-in module names if you
ever wonder if your local modules are clashing with built-in ones.
import sys # ๐๏ธ print all built-in module names print(sys.builtin_module_names)
The error is also caused if one of the modules you are importing imports a module that has the same name as a local file in your project.
requests
and requests
imports datetime
, but you have a local file called datetime.py
, you would still get the error.Another common cause of the error is having circular imports between files.
Let's look at an example that uses the modules first_module.py
and
second_module.py
.
Here is the code for first_module.py
:
# ๐๏ธ Imports second_module import second_module def first_function(): print('first function') # โ๏ธ AttributeError: partially initialized module 'second_module' # has no attribute 'second_function' (most likely due to a circular import) second_module.second_function()
And here is the code for second_module.py
:
# ๐๏ธ Imports first_module import first_module def second_function(): print('second function') first_module.first_function()
Notice that the two modules import each other. This is called a circular dependency.
Here is the updated second_module.py
file.
def second_function(): print('second function') # ๐๏ธ Now importing in a function scope import first_module first_module.first_function()
However, a much better approach is to create a file third_module.py
which
imports first_module
and second_module
and uses them.
Here is the updated code for first_module.py
.
def first_function(): print('first function')
Here is the updated code for second_module.py
.
def second_function(): print('second function')
And here is the code for third_module.py
which makes use of both of the
previous modules.
import first_module import second_module first_module.first_function() second_module.second_function()
Now we don't have any circular imports (importing members between the same modules), which makes our code much easier to reason about.
If none of the suggestions helped, use the dir()
function to print all of the
attributes the imported module has.
import requests # ๐๏ธ ['__builtins__', '__cached__', '__doc__', '__file__', # '__loader__', '__name__', '__package__', '__spec__', 'requests'] print(dir(requests))
If you pass a module object to the dir() function, it returns a list of names of the module's attributes.
If you try to access any attribute that is not in this list, you will get an error.
This means that you are either trying to access an attribute that is not present on the module, or you have an incorrect import statement.
To solve the Python "AttributeError: partially initialized module has no
attribute", make sure you haven't named your local modules with names of remote
modules, e.g. requests.py
or datetime.py
and remove any circular
dependencies in import statements.