Python 3 个导入与内部冲突 "parser"
Python 3 import conflicts with internal "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 内部解析器保留的。但是我无法更改目录名称 "parser",因为它已被到处使用。
我该如何解决这个问题?
python 有一个模块 parser ,你想导入它没有的 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
要被接受为 Python 包,目录必须有一个 __init__.py
文件。
可以访问此文件中声明的变量,就好像包是一个常规模块一样。它也可以是空的。
tl;dr:将一个空的 __init__.py
文件添加到目录,它应该可以工作。
.
├── 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 内部解析器保留的。但是我无法更改目录名称 "parser",因为它已被到处使用。
我该如何解决这个问题?
python 有一个模块 parser ,你想导入它没有的 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
要被接受为 Python 包,目录必须有一个 __init__.py
文件。
可以访问此文件中声明的变量,就好像包是一个常规模块一样。它也可以是空的。
tl;dr:将一个空的 __init__.py
文件添加到目录,它应该可以工作。