首页 > 解决方案 > 为什么相对进口如此受限制?

问题描述

带目录:

app/
    sub1/
        __init__.py
        module1.py
    sub2/
        __init__.py
        test.py

我想象导入一个模块要做的是:

  1. 创建一个范围(或线程?)

  2. 在该范围内运行 module.py

from ..sub import module1在顶层无效test.py

open('../sub1/module1.py', 'r')有效!

所以它是可读的,但不可导入。

从类似的东西开始import moudule as *

exec(open('../sub1/module1.py', 'r').read())

通过在特定范围内执行此脚本并命名该范围来做进一步的事情。

class 将提供一个范围,调用类变量也类似于调用模块变量。

import module1 as cus

class Module:
    exec(open('../sub1/module1.py', 'r').read(), locals(), locals())
cus = Mudule()
cus.function_inside_module1()

函数在作用域下exec(object[, globals[, locals]])运行,并将变量存储到. (我猜)objectglobalslocals

由于 argumentglobalslocals都是locals()class Module,这就像我想象的 import 要做的。

如果这个工作正常,我猜模块下的模块可以写成嵌套类。

这种奇怪的导入会导致什么样的问题?

如果不是,为什么文件可读但不可导入(有顶级限制)?

编辑

@user2357112 抱歉,我不知道如何写多行注释:

这会给出您要求加载父包的行为吗?

class sub1:
    exec(open('../sub1/__init__.py', 'r').read(), locals(), locals())
    class Module:
        exec(open('../sub1/module1.py', 'r').read(), locals(), locals())
cus = sub1.Module()
del sub1

标签: pythonpython-3.ximportmodulerelative-path

解决方案


相对导入不是目录遍历机制。from ..a import b并不意味着“上一个目录,进入a目录,然后加载b.py”。意思是“导入当前包的父包b的子模块的成员”。这通常看起来很像目录遍历所做的事情,但并不相同,尤其是对于涉及命名空间包、自定义模块加载器或操作的情况。asys.modules

sub2没有父包。试图引用一个不存在的父包是一个错误。此外,如果您test.py直接按文件名运行,sub2则根本不被视为包。


推荐阅读