0

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

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

直到 Python 3.2(我相信),可以在 a 子文件夹中使用相对引用导入 Abstract 类:

from .. import Abstract

使用 Python 3.6 会产生错误消息:

ValueError: attempted relative import beyond top-level package

经典(和丑陋)的替代方法是在运行时将父文件夹添加到路径中:

import sys
import os

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

但这也失败了:

ModuleNotFoundError: No module named 'programme'

现在用 Python 3.6 是如何做到的?最好在运行时不修改路径。

4

2 回答 2

2

您可以在顶层使用 __init__.py,program/__init__.py,然后从 program 导入子模块。

例子:

# 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
于 2020-01-24T16:39:23.373 回答
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

于 2020-01-23T15:56:42.067 回答