【问题标题】:Import classes from parent folder in Python 3.6从 Python 3.6 中的父文件夹导入类
【发布时间】:2020-05-09 21:40:20
【问题描述】:

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

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 是如何做到这一点的?最好不要在运行时修改路径。

【问题讨论】:

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


【解决方案1】:

你可以在顶层使用一个__init__.py,program/__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

【讨论】:

  • 此解决方案不起作用。按照您的建议运行会返回错误:Error while finding module specification for 'programme.classA.ClassA' (ModuleNotFoundError: No module named 'programme')。从pkgA 文件夹运行classA.py 将返回:ModuleNotFoundError: No module named 'programme'
【解决方案2】:

您需要比程序更高的级别。

这需要添加到代码中:

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

这在programme/pkgA 上执行python3.7 ClassA.py 时有效,它是从以下回复中挑选出来的:Ultimate answer to relative python imports

【讨论】:

  • 确实有效。但它会更干净,而不必在运行时摆弄路径。
猜你喜欢
  • 2020-04-26
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2018-12-24
相关资源
最近更新 更多