Python relative-import script two levels up - python

I've been struggling with imports in my package for the last hour.
I've got a directory structure like so:
main_package
|
| __init__.py
| folder_1
| | __init__.py
| | folder_2
| | | __init__.py
| | | script_a.py
| | | script_b.py
|
| folder_3
| | __init__.py
| | script_c.py
I want to access code in script_b.py as well as code from script_c.py from script_a.py. How can I do this?
If I put a simple import script_b inside script_a.py, when I run
from main_package.folder_1.folder_2 import script_b
I am met with an
ImportError: no module named "script_b"
For accessing script_c.py, I have no clue. I wasn't able to find any information about accessing files two levels up, but I know I can import files one level up with
from .. import some_module
How can I access both these files from script_a.py?

To access script_c and script_b from script_a, you would use:
from ...folder_3 import script_c
from . import script_b
Or if you use python3, you can import script_b from script_a by just using:
import script_b
However, you should probably use absolute imports:
from mypackage.folder_3 import script_c
from mypackage.folder1.folder2 import script_b
Also see: Absolute vs Relative imports

Related

No module named... in Django proyect

I have a pretty standart Django project and i can't find a way to import /middleware/utils/compare.py from /middleware/utils/request.py
This is the proyect tree:
|--middleware/
| |--utils/
| | |--compare.py
| | |--request.py
| |--__init__.py
| |--asgi.py
| |--settings.py
| |--urls.py
| |--views.py
| |--wsgi.py
|--manage.py
Where __init__.py, asgi.py, settings.py, urls.py, wsgi.py have no major modifications. (__init__.py is empty)
# middleware/views.py
from .utils.request import requests # This line works fine
# middleware/utils/request.py
from compare import compare # ModuleNotFoundError: No module named 'compare'
from .compare import compare # Attempted relative import beyond top-level package pylint(relative-beyond-top-level)
# ^^^ This line absolutly breaks my code, but it runs
from utils.compare import compare # ModuleNotFoundError: No module named 'utils'
from .utils.compare import compare # ModuleNotFoundError: No module named 'middleware.utils.utils'
Note: compare.py has a function named compare, i also tried renaming it but had the same problems.
This might be obvious, but i run the proyect with python manage.py runserver
Simply add empty __init__.py in utils folder.
And read more about it here:
https://docs.python.org/3/tutorial/modules.html#packages
Change your file tree like this,
|--middleware/
| |--utils/
| |--|__init__.py # Added this file
| | |--compare.py
| | |--request.py
| |--__init__.py
| |--asgi.py
| |--settings.py
| |--urls.py
| |--views.py
| |--wsgi.py
|--manage.py
And import like this,
from utils.compare import compare

relative paths in python not finding parent package

I have a file system like this at the moment.
app
|--__init__.py (empty)
|
|--domain
| |--__init__.py (empty)
| |--model.py
| |--questionmatcher.py
|
|--interface
| |--__init__.py (empty)
| |--basiccli.py
| |--userinterface.py
|
|--parser
| |--__init__.py (empty)
| |--json_loader.py
| |--parsing.py
|
|--testfiles
| |--__init__.py (empty)
| |--testsuite.py
I am trying to run the testsuite.py which will need to import classes from various files in directory.
I have tried this structure:
import unittest
from ..parser.json_loader import JsonLoader
from ..parser.parsing import get_vectors, parseThreadsFromFile, getPostsFromThreads
from ..domain import UniversalEncoder, SentBERT
class TestParsing(unittest.TestCase):
def test(self):
pass
class TestJson(unittest.TestCase):
def test(self):
pass
class TestModelEncoders(unittest.TestCase):
def test(self):
pass
if __name__ == "__main__":
unittest.main()
However when I go to run the test I get:
from ..parser.json_loader import JsonLoader
ImportError: attempted relative import with no known parent package
EDIT:
I have tried
from parser.json_loader import JsonLoader
but now I get
from parser.json_loader import JsonLoader
ModuleNotFoundError: No module named 'parser.json_loader'; 'parser' is not a package
you can add this package to your PYTHONPATH environmental variable:
export PYTHONPATH=$PYTHONPATH:/path/to/parser

How to relative import the *resource* itself?

How would I import config.py from the current working directory? Why does import ..config return the following error: ImportError: attempted relative import with no known parent package?
main_directory
|
|
|--sub_directory
| |
| |
| current_working_directory
|
|
config.py

Python Relative import not working

main_package
|
| __init__.py
| folder_1
| | __init__.py
| |script_a.py
| |
| folder_2
| | __init__.py
| | script_b.py
I want to access script_b from script_a and import b_class with relative import
script_a.py:
from ..folder2.script_b import b_class
Gives me error => ValueError: attempted relative import beyond top-level package
http://dosya.co/y6aqrgp993fu/main_package.rar.html
try, as it is package
from main_package.folder_2.script_b import b_class
OR
from .main_package.folder_2.script_b import b_class
OR (May be patch)
import sys
sys.path.append(pathofyourproject) // `/home/prject`
import folder_2.script_b.py

How to run script with Django settings in subdirectory without relative project path

I want to execute the seeds.py script located in restaurants_project/scripts/. This seed file would populate my database with restaurant records based on the CSV data within the same folder by using my Django model Restaurant. I've found that the only way to include the project settings (i.e. restaurant_project.settings) along with my necessary models was to sys.path.append('MY_PROJECTS_RELATIVE_PATH') in the seeds file. I obviously don't want to do this in production (or do i?) so what's the best way to include those settings without getting the following ImportError:
ImportError: Could not import settings 'restaurants_project.settings' (Is it on sys.path? Is there an import error in the settings file?): No module named 'restaurants_project'
Directory Tree:
|___restaurants_project
| |______init__.py
| |______pycache__
| | |______init__.cpython-34.pyc
| | |____settings.cpython-34.pyc
| |____settings.py
| |____urls.py
| |____wsgi.py
|____restaurants
| |______init__.py
| |______pycache__
| | |______init__.cpython-34.pyc
| | |____admin.cpython-34.pyc
| | |____models.cpython-34.pyc
| |____admin.py
| |____migrations
| | |______init__.py
| |____models.py
| |____tests.py
| |____views.py
|____scripts
| |______init__.py
| |______pycache__
| | |______init__.cpython-34.pyc
| |____restaurant_inspections_2014.csv
| |____seeds.py
| |____unique_restaurant_ids.txt
seeds.py:
import os, sys
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'restaurants_project.settings')
import django
django.setup()
import csv
csvfile = open('restaurant_inspections_2014.csv')
reader = csv.reader(csvfile)
headers = next(reader, None)
for row in reader:
print(row)
import pdb; pdb.set_trace()
The best way to write a script that uses the settings of a project is to write a custom management command:
https://docs.djangoproject.com/en/1.8/howto/custom-management-commands/
Basically you should wrap your script inside a class that extends BaseCommand and put it inside the management/commands directory of an app.

Categories