Проблема импорта класса Python 3 из подпапок - PullRequest
0 голосов
/ 02 марта 2019

У меня странная проблема с импортом классов из подпапок.

Я использую Python 3.6, поэтому __init__.py не требуется в подпапках.

У меня следующая файловая структура:

root
├── script.py (main)
└── custom
    ├── class1.py
    └── class2.py

Это script.py:

from custom.class1 import Class1
from custom.class2 import Class2

if __name__ == '__main__':
    cl1 = Class1()
    cl2 = Class2()

Это class1.py:

class Class1():
    def __init__(self):
        print('Class1')

if __name__ == '__main__':
    cl1 = Class1()

Это class2.py, который также импортирует class1:

from class1 import Class1

class Class2():
    def __init__(self):
        cl1 = Class1()
        print('Class2')

if __name__ == '__main__':
    cl2 = Class2()

А теперь проблема:

Работает без ошибок, когда я запускаю python class1.py в подпапке custom.

Работает безошибка, когда я запускаю python class2.py в подпапке custom.

Но когда я запускаю python script.py в папке root, я получаю следующую ошибку:

Traceback (most recent call last):
  File .... in <module>
    from custom.class2 import Class2
  File .... line 1, in <module>
    from class1 import Class1
ModuleNotFoundError: No module named 'class1'

Как это можно исправить таким образом, чтобы скрипты в подпапках custom могли запускаться самостоятельно, а также скрипт в папке root работает?

1 Ответ

0 голосов
/ 02 марта 2019

Проблема в том, что вы используете custom.class2 внутри script.py, что означает, что при запуске custom.class2 вы все еще находитесь в каталоге root.

Чтобы это исправить, вы должны заменитьfrom class1 import Class1 из class2.py с from custom.class1 import Class1.

Если вам нужно запустить файл из любого рабочего каталога, вы можете заменить его содержимое следующим:

import os
import sys

path = os.path.abspath(os.path.dirname(__file__))
if not path in sys.path:
    sys.path.append(path)

from class1 import Class1

class Class2():
    def __init__(self):
        cl1 = Class1()
        print('Class2')

if __name__ == '__main__':
    cl2 = Class2()

Код добавляет путь к файлу в список sys.path, который содержит различные пути, из которых вы можете импортировать модули.

...