Import via relative path global variables module - python

Here is my directory structure:
.
`-- parent
|-- child
| |-- globalvar.py
| |-- __init__.py
| `-- subchild
| |-- __init__.py
| `-- module.py
`-- main.py
The globalvar.py in the child directory consist of the global variables that I would like to use in my application:
globalvar.py
def variables():
global event_id
event_id = 2100
In main.py, I'm calling the globalvar.py via import to initialize (child.globalvar.variables):
main.py
import child.globalvar
from child.subchild.module import display
child.globalvar.variables()
display()
Here is what I in my module.py file under the directory subchild:
from ..globalvar import variables
def display():
print globalvar.event_id
This is the traceback I get when I execute main.py:
Traceback (most recent call last):
File "main.py", line 6, in <module>
display()
File "/parent/child/subchild/module.py", line 5, in display
print globalvar.event_id
NameError: global name 'globalvar' is not defined
How do I fix this?

I was able to fix it by changing the import statement in my module.py file:
BEFORE:
from ..globalvar import variables
AFTER:
from .. import globalvar

Related

Using common constants module leads to circular import

I want to import constants from a constants module from two different modules, but I get the following error:
Traceback (most recent call last):
File "C:\Temp\tmp\pycircular\pycircular\pycircular.py", line 2, in <module>
from my_classes.foo import Foo
File "C:\Temp\tmp\pycircular\pycircular\my_classes\foo.py", line 1, in <module>
from pycircular.constants import ANOTHER_CONSTANT
File "C:\Temp\tmp\pycircular\pycircular\pycircular.py", line 2, in <module>
from my_classes.foo import Foo
ImportError: cannot import name 'Foo' from partially initialized module 'my_classes.foo' (most likely due to a circular import) (C:\Temp\tmp\pycircular\pycircular\my_classes\foo.py)
My project structure is the following:
|-constants.py
|-my_classes
| |-foo.py
| |-__init__.py
|-pycircular.py
|-__init__.py
# =============
# pycircular.py
# =============
from constants import SOME_CONSTANT
from my_classes.foo import Foo
def main():
print(SOME_CONSTANT)
my_foo = Foo()
my_foo.do_something()
if __name__ == "__main__":
main()
# =============
# foo.py
# =============
from pycircular.constants import ANOTHER_CONSTANT
class Foo:
def do_something(self):
print(ANOTHER_CONSTANT)
# =============
# constants.py
# =============
ANOTHER_CONSTANT = "ANOTHER"
SOME_CONSTANT = "CONSTANT"
I assume that it is the same problem as solved here https://stackoverflow.com/a/62303448/2021763.
But I really do not get why from my_classes.foo import Foo in pycircular.py is called a second time.
Update:
After renaming the package pycircular to pycircular_pack it worked in PyCharm.
But it only works because in Pycharm the option Add content roots to to PYTHONPATH is automatically set.
The output of sys.path is ['C:\\Temp\\tmp\\pycircular\\pycircular_pack', 'C:\\Temp\\tmp\\pycircular', 'C:\\Tools\\miniconda\\envs\\my_env\\python39.zip', 'C:\\Tools\\miniconda\\envs\\my_env\\DLLs', 'C:\\Tools\\miniconda\\envs\\my_env\\lib', 'C:\\Tools\\miniconda\\envs\\my_env', 'C:\\Tools\\miniconda\\envs\\my_env\\lib\\site-packages']
Without the option the output is ['C:\\Temp\\tmp\\pycircular\\pycircular_pack', 'C:\\Tools\\miniconda\\envs\\my_env\\python39.zip', 'C:\\Tools\\miniconda\\envs\\my_env\\DLLs', 'C:\\Tools\\miniconda\\envs\\my_env\\lib', 'C:\\Tools\\miniconda\\envs\\my_env', 'C:\\Tools\\miniconda\\envs\\my_env\\lib\\site-packages']
And without the option I only get it to work with absolute imports.
# pycircular.py
from constants import SOME_CONSTANT
from my_classes.foo import Foo
...
# foo.py
from constants import ANOTHER_CONSTANT
To elaborate based on the comments and edit:
After renaming the package pycircular to pycircular_pack it worked in PyCharm. But it only works because in Pycharm the option Add content roots to to PYTHONPATH is automatically set.
You should make sure the package directory is not set as a content root or source root. The directory hosting the package directory should be set as source root.
C:\Temp\tmp\pycircular # <- source root
|- pycircular_pack # <- not set as anything
| |- constants.py
| |- my_classes
| | |- foo.py
| | |- __init__.py
| |- pycircular.py
| |- __init__.py
|- other_file.py # <- for illustration's sake
Now your sys.path will be set to include C:\Temp\tmp\pycircular only and there will be exactly one way to import things from your module.
Namely,
other_file.py (outside the package) will be able to use the package as pycircular_pack
pycircular_pack/*.py can refer to modules in the pycircular_pack package by either
(e.g.) from .constants import ... (relative import from current package), or
(e.g.) from pycircular_pack.constants import ... (absolute import)
pycircular_pack/my_classes/*.py can refer to modules in the pycircular_pack package by either
(e.g.) from ..constants import ... (relative import from parent package), or
(e.g.) from pycircular_pack.constants import ... (absolute import)
If your pycircular_pack package would contain a runnable script, e.g. a CLI as pycircular_pack/cli.py, then the correct way to run that script on the command line would be to use python -m pycircular_pack.cli; this has Python set up the path just like we want here, where python pycircular_pack/cli.py would not do the right thing.

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

ModuleNotFoundError: No module named 'src' in python

I have the following folder structure:
src
|_ __init__.py
example.py
test
|_ test.py
# __init__.py
class API:
def something(self):
print('folder src | file __init__')
# example.py
class Example:
def doingSomething(self):
print('folder src | file example')
# test.py
import src
from src.example import Example
class Test:
def somethingElse(self):
print('folder test | file test')
when I run the test.py file, I get the following error:
Traceback (most recent call last):
File "<my path>\test\test.py", line 1, in <module>
import src
ModuleNotFoundError: No module named 'src'
Unless you import the example module in your src/__init__.py file, you need to specify the module name (i.e., example) within the package (i.e., src).
from src.example import Example
You don't actually need to include the "src" folder in your path. For example, if you're folder structure looks like this:
src
app1
models1.py
views1.py
app2
models2.py
views2.py
You can import models2.py into views2.py like this:
from .models2 import ClassName

Import multiple subdirectories/modules as if they are just one module

so I have a module/directory called A and it has init.py file and in it, it has another module/directory called B which have its init.py and a file called function.py which has a function called dummy()
here is the structure of directories
A
|-- __init__.py
|
|-- B
|
|-- __init__.py
|-- function.py
so what I want is to be on the same directory that contains directory A and do that
from A import *
dummy()
what I have done is do that in B/init.py
from dummy import *
and that in A/init.py
import B
and I can do that
from A.B import *
I want to write A instead of A.B
I changed your import code a bit and it seems to work now like you wanted.
So in the B directory's init.py it has:
# __init__.py in B
from .function import *
In the A directory's init.py:
# __init__.py in A
from .B import *
Now, when I run Python shell in the directory that contains A and and use from A import *, it calls dummy() with no problem.
However, there are discussions on using wildcard imports in Python. Check this post for example: Should wildcard import be avoided?

Import a file from another directory

I have a file call entryPoint.py :
from .commonLib.deviceLib import *
And I have a file called deviceLib.py :
import math
import sys
import logging
import requests
import this
class DeviceLib(object):
def __init__(self, connectionDb):
self.__db = connectionDb
The tree is like this :
/test
entryPoint.py
/commonLib
__init__.py
deviceLib.py
When I execute python entryPoint.py I get the error : Attempted relative import in non-package. Please help me.
use sys.path.append to append the directory where your python file (module is). E.g if your entryPoint.py is inside address directory
import sys
sys.path.append('/path/to/your/module/address/')
import entryPoint
There should be __init__.py in the folder both /test and /commonLib reside.
then just do
from commonLib import deviceLib
For example
sound
|-- effects
| |-- echo.py
| |-- __init__.py
| |-- reverse.py
| `-- surround.py
|-- filters
| |-- equalizer.py
| |-- __init__.py
| |-- karaoke.py
| `-- vocoder.py
|-- formats
| |-- aiffread.py
| |-- aiffwrite.py
| |-- auread.py
| |-- auwrite.py
| |-- __init__.py
| |-- wavread.py
| `-- wavwrite.py
`-- __init__.py
lets assume you are right now opened wavread.py in format subdirecory, you can import karaoke.py from filters by just
from filters import karaoke
More information Here,
https://www.python-course.eu/python3_packages.php
To import a file from another directory you can use this code :
import sys
sys.path.insert(0, 'folder destination')
import file
As you can see here we included the path so python will look for the file in that path as well.

Categories