I have a Python 3.9.2 project with the following directory structure:
lib/
├─ mod1.py
├─ mod2.py
├─ __init__.py
main.py
In /main.py, I have from lib import mod1. In /lib/mod1.py, I have import mod2. When I run /main.py, I receive the following error:
Traceback (most recent call last):
File "/main.py", line 1, in <module>
from lib import mod1
File "/lib/init.py", line 1, in <module>
import mod2
ModuleNotFoundError: No module named 'mod2'
Why is this happening? When I change the code in /lib/mod1.py to say from lib import mod2, the code works fine, but I don't understand why that fixes it. Shouldn't I be able to import /lib/mod2.py the way I originally tried, since both mod1.py and mod2.py are in the same directory?
In /lib/mod1.py, you probably want to do:
# relative import - entire module
from . import mod2
# relative import - specific piece
from .mod2 import foo
or
# absolute import - entire module
from lib import mod2
# absolute import - specific piece
from lib.mod2 import foo
The correct way to import things is really tricky in Python because it depends on where you run the script from.
If you run the code from the root directory, import mod2 causes problems, but
If you were to run /lib/mod1.py (say it were run-able) from inside lib, then import mod2 would be correct and the alternatives above would cause errors.
Related
My directory structure looks like this:
- scripts
- script.py
- app
- foo
- connect.py
- bar
- __init__.py
- random.py
The __init__.py file in bar/ looks like
from bar.random import Random
__all__ = [ "Random" ]
and connect.py has an import
from bar import Random
I'm trying to execute script.py from the root directory via python scripts/script.py which is attempting to import from foo.py
from os import getcwd
from sys import path
path.append(getcwd())
from app.foo.connect import Connect
and getting:
Traceback (most recent call last):
File "scripts/script.py", line 19, in <module>
from app.foo.connect import Connect
File "/home/user/project/app/foo/connect.py", line 17, in <module>
from bar import Random
ModuleNotFoundError: No module named 'bar'
When running the app through its main, everything works. But when trying to execute a specific script attempting to import from a subdirectory in app/ I get the traceback.
What am I doing wrong?
The correct import of Random in connect.py is from app.bar.random import Random.
Also include __init__.py file in the app folder and connect folder.
You also do not need the __all__ statement in the one __init__.py file you have. All the __init__.py files can be left blank.
enviroment: python3.8
directory:
test\
module1\
__init__.py
mod1.py
module2\
mod2.py
main.py
1. I can import a directory without __init__.py , why?
I want to check how exactly init.py work, so I import the module1 and module2 in main.py
# test\main.py
from module1 import mod1
from module2 import mod2
In my expectation, line2 should occur error, because I didn't create __init__.py in module2
But both of them can be imported.
Now, I'm confused about how exactly __init__.py work
2. I can't import those package which is imported in __init__.py
I try to import mod1.py in main.py in this way:
# test\main.py
import module1
module.mod1.mod1_print() # mod1_print() is a function which is defined in mod1.py
So I import mod1.py in test\module1\__init__.py :
# test\module1\__init__.py
import mod1
But when I execute main.py I got this error:
D:\>"C:/Program Files/Python38/python.exe" d:/test/main.py
Traceback (most recent call last):
File "d:/test/main.py", line 2, in <module>
import module1
File "d:\test\module1\__init__.py", line 1, in <module>
import mod1
ModuleNotFoundError: No module named 'mod1'
My question is:
If I want to import mod_print() in this form: module.mod1.mod1_print() , what should I do?
Python 3.3+ has Implicit Namespace Packages that allow it to create packages without an __init__.py file.
Allowing implicit namespace packages means that the requirement to provide an init.py file can be dropped completely, and affected portions can be installed into a common directory or split across multiple directories as distributions see fit.
see https://stackoverflow.com/a/37140173/9822 - python >= 3.3 dropped the requirement for __init__.py.
You could try something like this in module1/__init__.py:
import module1.mod1
I am currently using Python 3.7.
My project has the following structure:
runner.py
pkg1/
__init__.py (empty)
mod1.py
mod1_helpers.py
In mod1.py:
import mod1_helpers
# call some functions in mod1_helpers.py
In runner.py:
import pkg1.mod1
When I run runner.py, Python threw the following error:
File "..\pkg1\mod1.py", line 1, in <module>
import mod1_helpers
ModuleNotFoundError: No module named 'mod1_helpers'
The issue resolves when I manually add the path to pkg1 to sys.path in runner.py.
Could someone please advise the proper way to resolve this issue?
Since they're in the same directory you have to prefix import of mod1_helpers with a .
try this:
import .mod1_helpers
I'm new to Python (JS developer) and am trying to run a testing suite. My project folder structure is as such:
project/
__init__.py
libs/
__init__.py
s3panda.py
tests
__init__.py
tests_s3panda.py
In terminal, I'm running python tests_s3panda.py.
I don't understand how it's unable to find a local module:
Traceback (most recent call last): File "tests_s3panda.py", line 7,
in
from libs.s3panda import S3Panda ImportError: No module named libs.s3panda
tests_s3panda.py snippet:
from __future__ import absolute_import
import unittest
import pandas as pd
from libs.s3panda import S3Panda
class TestS3Panda(unittest.TestCase):
...
Doing from ..libs.s3panda import S3Panda for relative path, I get:
ValueError: Attempted relative import in non-package
I believe the fact that there is no init.py in the top-level folder means that Python is not aware that libs and tests are both part of the same module called project.
Try adding an __init__.py to your project folder, then write the import statement as from project.libs.s3panda import S3Panda. In general, you want to specify absolute imports rather than relative imports (When to use absolute imports).
I have a pytestlib package and modules as follows:
test.py is simply creating module2 and the module2 imports module1.
test.py code is working as expected if compiled and run directly in its own folder.
pyteslib\
- __init__.py
- module1.py
- module2.py
- test.py
module1.py
class Module1Class():
def __init__(self):
self.msg ="This message is from Module1Class"
module2.py
from module1 import Module1Class
class Module2Class():
def __init__(self):
module1_obj = Module1Class()
print(module1_obj.msg)
test.py
from module2 import Module2Class
module2_obj = Module2Class()
However; if I make this, a package, and import from another project I get an ImportModule error.
externaltest.py (In another project)
import sys
from pytestlib.module1 import Module1Class # No error importing module1
# from pytestlib.module2 import Module2Class # I have error if import module2
module1_obj = Module1Class()
# module2_obj = Module2Class() # I have error
I have this error:
Traceback (most recent call last):
File "X:/SDK/python/testimp/imp.py", line 3, in <module>
from pytestlib.module2 import Module2Class
File "C:\Program Files (x86)\Python35-32\lib\site-packages\pytestlib\module2.py", line 1, in <module>
from module1 import Module1Class
ImportError: No module named 'module1'
In short, after making the package, module1 cannot be found by the module2.py of the package. But as you see, module1 can be directly imported by externaltest.py. Package cannot import its own module.
Solution: use relative imports
from .module1 import ModuleClass1
Read this answer for a more complete explanation