2

I have folder structure as below

mypackage/
    __init__.py
    package1/
        __init__.py
        module1.py        # has ClassOne 
        module2.py        # has ClassTwo
        script.py
    package2/
        __init__.py
        module3.py        # has ClassThree
        module4.py        # has ClassFour

In script.py I want to access ClassFour from module4 so I am using relative imports like below

from ..module4 import ClassFour

c = ClassFour()

but I am getting en error

ValueError: attempted relative import beyond top-level package

I know I can solve this using

import sys

sys.path.append("path/to/my/module/")

But I am interested in solution with relative imports.

I referred few questions and tried the solutions like - How to do relative imports

And also tried to run my file using

python -m script

but no success

Sociopath
  • 13,068
  • 19
  • 47
  • 75
  • 1
    You could put `script.py` at the top-level of your package. Or you can import from the installed package via `from mypackage.package2.module4 import ClassFour`. Also note that `from ..module4 import ClassFour` will not succeed in any case because such a module doesn't exist. It should rather be `from ..package2.module4 import ClassFour` or `from ..package2 import ClassFour`, if you import it in `__init__.py`. – a_guest Sep 23 '19 at 10:49

2 Answers2

4

You just need to call package2 before calling module4 as,

from ..package2.module4 import ClassFour

as using single .. you can jump out of package1 but didn't get access of package2 and it's file.

For example you can look into the following structure.

enter image description here

Recall the file contents:

package1/module2.py contains a function, function1.
package2/__init__.py contains a class, class1.
package2/subpackage1/module5.py contains a function, function2.

You can import class1 and function2 into the package2/module3.py file this way:

from . import class1
from .subpackage1.module5 import function2

for more reference you can visit this link: Reference

Lokesh
  • 496
  • 4
  • 11
1

To run your script inside the package you can do:

python -m mypackage.package1.script

If you didn't install the package (e.g. via pip) then you need invoke that command from the parent directory of mypackage (otherwise any directory will do).

For this however you also need to correct the import you are using. At the moment ..module4 doesn't point to an existing module. Instead it should be

from ..package2.module4 import ClassFour

Or if you imported ClassFour in package2/__init__.py then you can also do:

from ..package2 import ClassFour
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • Thanks it worked when I run the command with `python -m mypackage.package1.script` but how can I install the package via pip to run from other directory – Sociopath Sep 23 '19 at 11:12
  • @AkshayNevrekar You basically need to create a `setup.py` file that contains the relevant information. Then you can install from the parent directory of `mypackage` via `pip install .`. You can find out more [from the docs](https://python-packaging.readthedocs.io/en/latest/). – a_guest Sep 23 '19 at 13:19