0

I have a Python project with the following structure:

├── main.py
├── pack1
│   ├── __init__.py
│   ├── mod1
│   │   ├── __init__.py
│   │   └── request.py
│   ├── mod1.py
│   └── mod2.py

The content of main.py is:

from pack1 import mod1
from pack1.mod1.request import Mod1Request

my_class = mod1.Mod1Class()
my_request = Mod1Request()

if __name__ == '__main__':
    print(repr(my_request))
    print(repr(my_class))

The content of request.py and mod1.py is:

# request.py
class Mod1Request(object):
    pass

# mod1.py
class Mod1Class(object):
    pass

When I run it, I get this error:

Traceback (most recent call last):
  File "/Users/dohong/dev/import_traps/main.py", line 4, in <module>
    my_class = mod1.Mod1Class()
AttributeError: module 'pack1.mod1' has no attribute 'Mod1Class'

I have both a mod1.py file and a mod1 directory in my pack1 package. How can I properly import the Mod1Class from mod1.py while also keeping the imports from the mod1 directory working?

2
  • I suspect the issue is that the second import statement overwrites the contents of the mod1 namespace. You can check whether this is true by printing the content of the dir command. Take a look at The import system for details on how imports are managed. Commented Dec 24, 2024 at 9:51
  • Following on from the previous comment, you could see if it works if you alias the first import namespace, e.g., from pack1 import mod1 as newmod1, followed with my_class = newmod1.Mod1Class(). Commented Dec 24, 2024 at 10:19

1 Answer 1

2

The best way to deal with clashing file names would be to rename one of the files. If possible please rename mod1.py file to something else or you can place the file into some directory like pack2.

If that is not possible, there is one roundabout way to import a file with its file path. The changes to main.py will be as follows, however it is advised to not use it and just rename the file by simply adding prefix or suffix.

import importlib.util

spec = importlib.util.spec_from_file_location("mod1_class", "pack1/mod1.py")
mod1_class = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod1_class)

from pack1.mod1.request import Mod1Request

my_class = mod1_class.Mod1Class()
my_request = Mod1Request()

if __name__ == '__main__':
    print(repr(my_request))
    print(repr(my_class))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.