How to split python script into several files using relative imports? - python

I have import.py script. I want to extract some code into a separate file, say, m1.py:
$ ls
import.py m1.py
$ cat import.py
from .m1 import a
a()
$ cat m1.py
def a():
print('it works')
$ python import.py
Traceback (most recent call last):
File "import.py", line 1, in <module>
from .m1 import a
ModuleNotFoundError: No module named '__main__.m1'; '__main__' is not a package
When I switch to absolute import, it works. But I don't want accidentally importing other module. I want to be sure module from script's directory is imported. How do I make it work? Or what am I doing wrong?

If you're not overriding the built in modules. By default, python looks first in your current directory for the file name you want to import. So if there is another script having the same name in another directory, only the one you have in the current directory is the one that will be imported.
Then, you could import using the absolute import.
from m1 import a
a()
You can check this post out, for more infrotmation about importing in python.
To make sure that the one your importing isn't the built in. You can create your own package in the current directory for example,"my_package" and have your module m1 moved in it. Then you can import by:
from my_package import m1
m1.a()

Add __init__.py in the directory where m1.py is.
EDIT : Run it as a package from the previous working directory. cd .. && python -m prev_dir.import

Related

Trouble execute project python in bash

i'm trying execute project python in terminal but appear this error:
(base) hopu#docker-manager1:~/bentoml-airquality$ python src/main.py
Traceback (most recent call last):
File "src/main.py", line 7, in <module>
from src import VERSION, SERVICE, DOCKER_IMAGE_NAME
ModuleNotFoundError: No module named 'src'
The project hierarchy is as follows:
Project hierarchy
If I execute project with any IDE, it works well.
Your PYTHONPATH is determined by the directory your python executable is located, not from where you're executing it. For this reason, you should be able to import the files directly, and not from source. You're trying to import from /src, but your path is already in there. Maybe something like this might work:
from . import VERSION, SERVICE, DOCKER_IMAGE_NAME
The interpretor is right. For from src import VERSION, SERVICE, DOCKER_IMAGE_NAME to be valid, src has to be a module or package accessible from the Python path. The problem is that the python program looks in the current directory to search for the modules or packages to run, but the current directory is not added to the Python path. So it does find the src/main.py module, but inside the interpretor it cannot find the src package.
What can be done?
add the directory containing src to the Python path
On a Unix-like system, it can be done simply with:
PYTHONPATH=".:$PYTHONPATH" python src/main.py
start the module as a package element:
python -m src.main
That second way has an additional gift: you can then use the Pythonic from . import ....

How can I import python modules from outside the module's project structure without getting a ModuleNotFoundError?

I created a python project, using Pycharm if it matters, that looks like this:
outer_dir/
outside_main.py
module_example/
module_main.py
tests/
test_1.py
…
level_1/
foo_1.py
level_2/
foo_2.py
main.py calls functions from foo_1.py
foo_1.py calls functions from foo_2.py
The general use case I'm trying to emulate is a python "package" or repo called module_example that has been downloaded and used by outside_main.py at the same level as the top-level package directory.
Here's how module_main.py looks:
# module_main.py
from level_1.foo_1 import foo_function_1
from level_1.level_2.foo_2 import foo_function_2
def main():
print(foo_1())
print(foo_2())
if __name__ == "__main__":
main()
And I can call this top level script from test_1.py just fine like this:
# test_1.py
from module_main import main
if __name__ == "__main__":
main()
However, when I try to use main() from outside the module_example directory, with code like this:
# outside_main.py
from module_example.module_main import main
if __name__ == "__main__":
main()
I get this error:
Traceback (most recent call last):
File "/path/to/outside_main.py", line 1, in <module>
from module_example.module_main import main
File "/path/to/module_example/module_main.py", line 1, in <module>
from level_1.foo_1 import foo_function_1
ModuleNotFoundError: No module named 'level_1'
What seems to be happening is that regardless of directory of the python script being imported, its own imports are being searched for relative to the directory from which the main script is executed.
I'm looking for a method of importing that works equally whether I'm calling outside_main.py or test_1.py, and regardless of what directory the terminal is currently pointing at.
I've read this post about how python imports work, and it basically suggests I'm out of luck, but that makes no sense to me, all I'm trying to do is emulate using someone's open source library from github, they usually have a tests folder within their repo, that works fine, but also I can just unzip the entire repo in my project and call import on their py files without issue. How do they do it?
Before entering the hell of sys.path-patching, I would suggest to wrap your code that currently lives in module_example into a package_example directory, add a setup.py and throw a number of __init__.py in.
Make package_example a git repo.
In every other project where you want to use module_example.[...], you create a venv and pip -e /path/to/package_example.
outer_dir/
outside_main.py
package_example/
.git/
...
setup.py
module_example/
__init__.py
module_main.py
tests/
...
where __init__.py (one in each subdirectory that contains modules that are to be imported) can just be empty files and setup.py has to be filled according to the distutils documentation.
Solution 1:
Use explicit relative imports (relative to the files inside the directory module_example). Note that the usage of implicit relative imports has already been removed in Python3
Implicit relative imports should never be used and have been removed in Python 3.
outer_dir/module_example/module_main.py
# Note the "." in the beginning signifying it is located in the current folder (use ".." to go to parent folder)
from .level_1.foo_1 import foo_function_1
from .level_1.level_2.foo_2 import foo_function_2
# All the rest the same
Solution 2:
Include the path to module_example in your PYTHONPATH environment variable (or you can also choose to update sys.path directly)
export PYTHONPATH=$(pwd):$(pwd)/module_example
Output:
Both solutions above was successful for me.
Before the fix:
$ python3 outside_main.py
Traceback (most recent call last):
File "outside_main.py", line 1, in <module>
from module_example.module_main import main
File "/home/nponcian/Documents/PearlPay/Program/2021_07Jul_31_StackOverflow/1/module_example/module_main.py", line 1, in <module>
from level_1.foo_1 import foo_function_1
ModuleNotFoundError: No module named 'level_1'
After the fix:
$ python3 outside_main.py
This is foo_function_1
This is foo_function_2

I need help understanding why python convert my package into modules and then give me error

Sorry if this a dumb question but i could not find similar question like this, Can someone help me understand the absolute import and how importing actually works in python, I watched a video where the instructor created two package one called package1 and package2, in the package2 this has a sub_package since am using python 3 i recreated the video topic and the above I placed an init file to some of the packages but not all because init is not really needed in the first place. I also have a root_file which is in the main directory of the overall project top level, this root_file module or script can access all the package, now when I import all the module via their package and sub-package into the root_file I have a function and name in the module to be printed out so when called from root_file.py I know who is who, this work fine, however, my issue is now when I try to absolute import from (package2 / module name = file2) into (package1 / module name = file1) I get a dirty big fat error
ModuleNotFoundError: No module named 'package2'
Traceback (most recent call last):
from package2 import file2
ModuleNotFoundError: No module named 'package2'
However, the import above worked for the instructor.
also, the same error occurs when I even attempt the basic to import from same package1 file1 into package1 file 2 I get
Traceback (most recent call last):
File "/Users/ganiyu/Desktop/Python_import/package1/file1.py", line 2, in <module>
from package1.file2 import pkg_1_file_2_func
ModuleNotFoundError: No module named 'package1'
Why does it only work when I import call from the packages and module into root_File.py or can some try recreating my issue or give me my answer also i am lost on why python keeps saying that 'package2 ' or the i try with package one or sub_packed it says the packages are modules.
EDITED
I found out that vscode is the issue it work on pycharm very all import combination can someone assist me how to get this working on vscode because am lost.
Make sure package2 is in the same directory as your file1.py.
From just looking at your directories, you can just move the package2 folder into your package1 folder.
package1
package2
package2 files
file1.py
When you run Python scripts, the current directory comes first for looking for modules, but the PYTHONPATH is also used.
It appears that your PYTHONPATH is not being set when you use VS Code, and VS Code is running the script from its own directory. PyCharm must be either setting it by default to the project root, or running the script from the project root. Please refer to How to use PYTHONPATH with VSCode Python Extension for Debugging?

Python error ' ModuleNotFoundError:'

I am getting this error
Traceback (most recent call last):
File "Exporter.py", line 3, in <module>
import sys,getopt,got,datetime,codecs
File "C:\Users\Rohil\Desktop\GetOldTweets-python-master\got\__init__.py", line 1, in <module>
import models
ModuleNotFoundError: No module named 'models'
my directory tree is:
C:\Users\Rohil\Desktop\GetOldTweets-python-master\got
this contains 2 folders: manager and models and 1 __init__.py file with the code :
import models
import manager
i am executing a file with the path: C:\Users\Rohil\Desktop\GetOldTweets-python-master\Exporter.py
I can't figure out what the issue is. can anyone assist me?
Set the environment variable PYTHONPATH=C:\Users\Rohil\Desktop\GetOldTweets-python-master\got (how exactly, depends on your operating system)
If you have created a directory and sub-directory then follow the below steps and please keep in mind that a directory must have an __init__.py file for python to recognize it as a package.
First run this to see all paths being searched by python:
import sys
sys.path
You must be able to see your current working directory in that list.
Now import the sub-directory and the respective module that you want to use via the import command: import subdir.subdir.modulename as abc You should now be able to use the methods in that module.
As you can see in this screenshot above I have one parent directory and two sub-directories. Under the second sub-directory I have a module named CommonFunction. On the console to the right you can see my working directory after execution of sys.path.
Does the models folder has an __init__.py file inside it ? Only then, it will be recognized as a module by python and import models would make sense.
So,
Create an empty __init__.py file in the models subfolder and then the code should work without any issues.
You should also look at this answer.
if create d or using or custom python package
check our dir. correct.
** For python 3.7 user **
from. import module_name
If you are using python3 but are installing the API through 'pip install 'such and such'. It's not gonna work on python3 console. Therefore, you'd better use 'sudo python3 -m pip install 'such and such''. Then it's gonna work!
(at least for ubuntu stuff)
:)

Splitting my code into multiple files in Python 3

I wish to split my code into multiple files in Python 3.
I have the following files:
/hello
__init__.py
first.py
second.py
Where the contents of the above files are:
first.py
from hello.second import say_hello
say_hello()
second.py
def say_hello():
print("Hello World!")
But when I run:
python3 first.py
while in the hello directory I get the following error:
Traceback (most recent call last):
File "first.py", line 1, in <module>
from hello.second import say_hello
ImportError: No module named 'hello'
Swap out
from hello.second import say_hello
for
from second import say_hello
Your default Python path will include your current directory, so importing straight from second will work. You don't even need the __init__.py file for this. You do, however, need the __init__.py file if you wish to import from outside of the package:
$ python3
>>> from hello.second import say_hello
>>> # Works ok!
You shouldn't run python3 in the hello directory.
You should run it outside the hello directory and run
python3
>>> import hello.first
By the way, __init__.py is no longer needed in Python 3. See PEP 420.
Packages are not meant to be imported from the current directory.
It is possible to make it work using if/else tests or try/except handlers, but it's more work than it is worth.
Just cd .. so you aren't in the package's directory and it will work fine.

Categories