Python 3导入与内部“解析器”的冲突

时间:2018-06-11 10:07:54

标签: python parsing import name-collision

.
├── 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

经过一番调查,我了解到“解析器”是为python内部解析器保留的。但是我无法更改目录名称“parser”,因为它已被无处不在。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

python有一个模块parser,你要导入它没有的engine,如果你想尝试

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

您将看到parser模块不是您的parser模块。

简单地重命名您的parser文件夹,一切都会好的

<强>更新

您可以尝试使用from导入,例如:

from parser import engine

答案 1 :(得分:1)

要被接受为Python包,目录必须具有__init__.py文件 在此文件中声明的变量可以是访问,就像包是常规模块一样。它也可以是空的。

tl; dr:在目录中添加一个空的__init__.py文件,它应该可以正常工作。

答案 2 :(得分:0)

假设您的项目实际上包含在项目目录中,那么......

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。这应该完全按预期运行而不会出现名称冲突。在测试中使用类似的import语句,如果以相同的方式运行测试模块,它应该可以正常工作。

我用以下测试了这个。在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