Проблема с импортом в python

Рейтинг: 1Ответов: 2Опубликовано: 01.10.2014

Структура файлов такова:

/main
    /classes
        __init__.py
        a.py
        b.py
    __init__.py
    c.py

Суть проблемы: классы, которые лежат в a.py и b.py должны наследоваться от базового класса, одним из атрибутов которого является класс, который лежит в c.py. Я думаю, что это хорошая идея -- хранить базовые классы в __init__.py просто чтобы в папках не валялось лишних файлов.

На вот такую попытку импорта класса с компилятор начинает ругаться:

from .main.c import ClassC
# from .c import ClassC

Attempted relative import in non-package

Документация как-то не очень помогла и я не особо понимаю суть проблемы.

PS. Не рассмотрел ещё возможность запихивания файла c.py в отдельный каталог на том же уровне, но что-то подсказывает мне, что результат будет тот же.

Ответы

▲ 2

в a.py просто

from main.c import Class

без . перед main

▲ 1

Чтобы всё сработало как надо, необходимо, чтобы исполняемый файл лежал на уровень выше всех остальных файлов, тогда все относительные импорты будут работать. Пример:

main/
    main.py
    code/
        __init__.py
        abc.py
        classes/
            __init__.py
            a.py
            b.py

# main/code/abc.py
class ClassC( object ):
    def __init__( self ):
        super( ClassC, self ).__init__()
        self.c = 15

    def PrintC( self ):
        print self.c

# main/code/classes/__init__.py
from ..abc import ClassC

class BaseClass( object ):
    def __init__( self ):
        super( BaseClass, self ).__init__()
        self.class_c = ClassC()

    def GetClassC( self ):
        return self.class_c

# main/code/classes/a.py
from . import BaseClass

class ClassA( BaseClass ):
    """docstring for ClassA"""
    def __init__( self, a ):
        super( ClassA, self ).__init__()
        self.a = a

    def PrintA( self ):
        print self.a

# main/code/classes/b.py
from . import BaseClass

class ClassB( BaseClass ):
    """docstring for ClassB"""
    def __init__( self, b ):
        super( ClassB, self ).__init__()
        self.b = b

    def PrintB( self ):
        print self.b

# main/main.py
from code.classes.a import ClassA
from code.classes.b import ClassB

if __name__ == '__main__':
    a = ClassA( 5 )
    b = ClassB( 10 )
    c = a.GetClassC()
    a.PrintA()
    b.PrintB()
    c.PrintC()

Ну и вывод программы:

5
10
15

Проблема примера в том, что он сугубо абстрактный, и, не смотря на всю его кажущуюся простоту, разобраться в нём не так уж просто: всего у нас пять файлов, которые лежат в трёх вложенных папках.