Импорт Python 3 конфликтует с внутренним парсером - PullRequest
0 голосов
/ 11 июня 2018
.
├── gen.py
├── lexer
│   ├── engine.py
|   └── ...
└── parser
    ├── engine.py
    └── ...

Я пишу свой проект компилятора, но теперь я застрял с конфликтами импорта Python.В gen.py я хочу импортировать некоторую функцию для генерации кода, например

import lexer.engine   # OK
import parser.engine  # ModuleNotFoundError: No module named 'parser.engine'; 'parser' is not a package

. После некоторого исследования я узнал, что "parser" зарезервирован для внутреннего анализатора python.Но я не могу изменить имя каталога "парсер", так как он использовался везде.

Как мне решить проблему?

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

Предполагая, что ваш проект на самом деле содержится в каталоге проекта, например, ...

my_package
| 
├── gen.py
├── lexer
│   ├── __init__.py
│   ├── engine.py
|   └── ...
├── parser
|   ├── __init__.py
|   ├── engine.py
|   └── ...
├── tests  
|   ├── test_thingy.py

в gen.py:

import my_package.lexer.engine
import my_package.parser.engine

в родительском каталоге my_package, выможет работать python -m my_package.gen.Это должно работать точно так, как ожидается, без конфликтов имен.С аналогичными операторами импорта в ваших тестах, если вы выполняете свои тестовые модули таким же образом, все должно работать нормально.

Я проверил это со следующим.В E/work/temp/ у меня есть каталог с именем my_package.Он имеет следующую структуру.

my_package
    | 
    ├── __init__.py  # needed in python 2, but not 3
    ├── import_test_b.py
    ├── parser
    |   ├── __init__.py
    |   └── import_test_a.py
    └── tests  
        ├── __init__.py  # needed in python 2 but not python 3
        └── test_imports.py

import_test_a:

def test(num):
    return num+3

import_test_b:

from my_package.parser.import_test_a import tst

print(tst(4))

test_imports.py:

from my_package.parser.import_test_a import tst

import unittest

class TestTst(unittest.TestCase):
    def test_one(self):
        self.assertEqual(tst(4), 7)

if __name__ == '__main__':
    unittest.main()

в E/work/temp:

запуск: python -m my_package.import_test_b - выход = 7

запуск: python -m my_package.tests.test_imports выход:.

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
0 голосов
/ 15 июня 2018

Чтобы быть принятым как пакет Python, в каталоге должен быть файл __init__.py.
Доступ к переменным, объявленным в этом файле, может быть таким, как если бы пакет был обычным модулем.Это также может быть пустым.

tl; dr: Добавьте пустой каталог __init__.py в каталог, и он должен работать.

0 голосов
/ 11 июня 2018

Python имеет модуль парсер , и вы хотите импортировать engine, которого у него нет, если вы попытаетесь

import parser
print(dir(parser))
print(parser.__file__)

, и вы увидите, что *Модуль 1007 * не является вашим parser модулем.

Просто переименуйте вашу папку parser, и все будет хорошо

Обновление

Вы можете попробовать импортировать с from, например:

from parser import engine
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...