Why it is bad idea to use wildcard based imports?

In Python if you are using a function that is not defined in the local namespace, you have to import it.

Importing everything from a module (or file) is possible with a single line:

from mymodule import *

This is a bad idea however:

  • It could lead to conflicts between names defined locally and the ones imported.
  • It reduces code readability as developers will have a hard time knowing where names come from.
  • It clutters the local namespace, which makes debugging more difficult.

Imported names can change when you update your dependencies. A wildcard import which works today might be broken tomorrow.

To illustrate the problem, let's explore the following setup across two Python files:

import datetime

def datetimenow():
    now = datetime.datetime.now()
    return str(now.strftime("%Y-%m-%d %H:%M"))
methods.py

In the main.py file we import everything from the methods.py file:

from datetime import datetime
from methods import *

def main():
    print(f'{datetime.now().year}')
    now = datetimenow()
    print(now)

if __name__ == '__main__':
    main()
main.py

If you run this example by python main.py command, you get the following error:

Traceback (most recent call last):
  File "/home/xcke/git/python-sandbox/main.py", line 8, in <module>
    main()
  File "/home/xcke/git/python-sandbox/main.py", line 5, in main
    print(f'{datetime.now().year}')
AttributeError: module 'datetime' has no attribute 'now'

The problem here is datetime has no .now() attribute, but the function imported from the datetime actually has.

Python 3.9.5 (default, May 19 2021, 11:32:47) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> from datetime import datetime
>>> datetime.now().year
2021
>>> 

However, we have overridden the datetime object in the main module with the wildcard based import.

This is just a simple issue, but still might require some troubleshooting, so it is best to avoid using those * based imports.