Luís de Sousa
Luís de Sousa

Reputation: 6842

Import classes from parent folder in Python 3.6

In a certain programme I have an abstract class that should be implemented in two different sub-packages for different purposes. A simplified version of this structure is:

programme/
  __init__.py
  Abstract.py
  pkgA/
    __init__.py
    ClassA.py
  pkgB/
    __init__.py
    ClassB.py

Up to Python 3.2 (I believe), it was possible to import the Abstract class within the a subfolder with a relative reference:

from .. import Abstract

Which with Python 3.6 devolves the error message:

ValueError: attempted relative import beyond top-level package

The classical (and ugly) alternative is to add the parent folder to the path at run time:

import sys
import os

sys.path.append(os.getcwd() + '/..')
from programme import Abstract

But this also fails:

ModuleNotFoundError: No module named 'programme'

How is this now done with Python 3.6? Preferably without modifying the path at run time.

Upvotes: 0

Views: 574

Answers (2)

AdielM
AdielM

Reputation: 31

You can use a __init__.py at the top level, programme/__init__.py, then import in the sub-module from programme.

Example:

# programme/__init__.py
from .Abstrac import Abstract
# programme/Abstract.py
class Abstract:
    def __init__(self):
        print('Abstract')
# programme/pkgA/ClassA.py
from programme import Abstract

class ClassA(Abstract):
    def __init__(self):
        super().__init__()

if __name__ == '__main__':
    a = ClassA()

Note, if you running as a script you should do:

$ cd programme
$ python -m programme.classA.ClassA
Abstract

Upvotes: 2

Jorge Mendes
Jorge Mendes

Reputation: 446

You need to a level higher than programme.

This needs to be added to the code:

import os, sys
current_dir = os.path.dirname(os.path.join(os.getcwd(), __file__))
sys.path.append(os.path.normpath(os.path.join(current_dir, '..', '..')))
from programme import Abstract

This has worked when doing python3.7 ClassA.py on programme/pkgA and it was picked from this response: Ultimate answer to relative python imports

Upvotes: 1

Related Questions