从Python 3.6的父文件夹导入类

时间:2020-01-23 15:07:36

标签: python python-3.x python-import

在某个程序中,我有一个抽象类,出于不同的目的,应该在两个不同的子程序包中实现该抽象类。此结构的简化版本是:

programme/
  __init__.py
  Abstract.py
  pkgA/
    __init__.py
    ClassA.py
  pkgB/
    __init__.py
    ClassB.py

在Python 3.2之前(我认为),可以使用a relative reference在子文件夹中导入Abstract类:

from .. import Abstract

使用Python 3.6改进了错误消息:

ValueError: attempted relative import beyond top-level package

classical (and ugly) alternative将在运行时将父文件夹添加到路径:

import sys
import os

sys.path.append(os.getcwd() + '/..')
from programme import Abstract

但这也会失败:

ModuleNotFoundError: No module named 'programme'

现在如何使用Python 3.6做到这一点?最好在运行时不修改路径。

2 个答案:

答案 0 :(得分:2)

您可以在顶层使用__init__.py程序/__init__.py,然后导入 程序中的子模块。

示例:

# programme/__init__.py
from .Abstrac import Abstract
# programme/Abstract.py
class Abstract:
    def __init__(self):
        print('Abstract')
# programme/pkgA/ClassA.py
from programme import Abstract

class ClassA(Abstract):
    def __init__(self):
        super().__init__()

if __name__ == '__main__':
    a = ClassA()

请注意,如果您以脚本身份运行,则应该执行以下操作:

$ cd programme
$ python -m programme.classA.ClassA
Abstract

答案 1 :(得分:1)

您需要高于计划的水平。

这需要添加到代码中:

import os, sys
current_dir = os.path.dirname(os.path.join(os.getcwd(), __file__))
sys.path.append(os.path.normpath(os.path.join(current_dir, '..', '..')))
from programme import Abstract

此操作在python3.7 ClassA.py上进行programme/pkgA时有效,它是从以下回复中选取的:Ultimate answer to relative python imports