Python 3 导入与内部"parser"冲突


.
├── 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内部解析器保留的。但是我无法更改目录名称"解析器",因为它已在任何地方使用。

如何解决问题?

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

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

python有一个模块解析器,如果你想导入它没有的engine,如果你愿意的话,试着

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

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

只需重命名您的parser文件夹,一切都会好起来

更新

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

from parser import engine

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

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

最新更新