首页 > 解决方案 > 如何声明子包,使其不与环境中的父包冲突?

问题描述

本地包将屏蔽环境中具有相同名称的任何其他包。

重现步骤:

mkdir pandas
touch pandas/__init__.py
python
>>> from pandas import DataFrame
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name DataFrame

如果我cd进入另一个目录,那么我可以导入,所以很明显我的包正在掩盖父级。

我举了一个例子pandas.DataFrame来说明我的观点。我真正想做的是在同一个包中创建模块层次结构。但是我的一些模块已经安装了pip,如果我尝试正确打包我的新模块,即使用相同的包名,我将无法访问那些已经安装在我的环境中的模块。

我想将每个模块保存在单独的项目/git 存储库中。

PS:我来自java

标签: python

解决方案


您可以将.符号用于本地包,如下所示:

from .pandas import DataFrame

顺便说一句,为了避免混淆,最好避免使用同名的知名包,如numpy,pandas等。否则你可以这样做

from mycompany.pandas import DataFrame

你有以下包结构:

mycompany/
__init__.py
pandas/
__init__.py

因此避免包命名在根包级别重叠。

如果您使用的是包结构,例如

mycompany/
__init__.py
tests/
__init__.py

你在外部调用一些框架,你有两种方法:

1)最坏的方法:手动将外部文件夹路径导入到当前路径:

import os
import sys
parentPath = os.path.abspath("..")
if parentPath not in sys.path:
    sys.path.insert(0, parentPath)

在此示例中../,如果之前未导入,我们将其导入到当前路径。

2)更好的方法。您使用 将包__init__.py导出tests/到外部世界:

# tests/__init__.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from my_class_A import ClassA
from my_class_B import ClassB

这样您就可以ClassA像往常一样在外部文件中导入该类:

# main.py
from tests import ClassA

给定以下结构:

mycompany/
__init__.py
main.py
tests/
__init__.py
my_class_A.py
my_class_B.py

(这只是为了有个想法,当然您必须根据您的用例调整导入和路径)。


推荐阅读