python导入不了包_python – 包内导入并不总是有效

编辑

我已经对此进行了更彻底的研究,并得出结论,这是核心Python或Python文档中的错误.更多信息可用于at this question and answer.

Python的PEP 8表明绝对优先于绝对超过相对进口.此问题有一个涉及相对导入的解决方法,并且导入机制中可能存在修复.

我在下面的原始答案提供了示例和解决方法.

原始答案

正如您所正确推断的那样,问题是循环依赖.在某些情况下,Python可以很好地处理这些,但是如果你得到太多的嵌套导入,它就会出现问题.

例如,如果你只有一个包级别,实际上很难让它破坏(没有相互导入),但是一旦你嵌套包,它就更像是相互导入,并且开始变得难以制作这行得通.这是一个引发错误的示例:

1级/ __ init__.py

from level1.level2 import Base

1级/ 2级别/ __ init__.py

from level1.level2.base import Base

from level1.level2.a import A

1级/级别2 / a.py

import level1.level2.base

class A(level1.level2.base.Base): pass

1级/级别2 /碱

class Base: pass

错误可以通过几种不同的方式“修复”(对于这个小案例),但许多潜在的修复都很脆弱.例如,如果您不需要在level2 __init__文件中导入A,则删除该导入将解决问题(并且您的程序稍后可以执行import level1.level2.aA),但如果您的包变得更复杂,那么将再次看到错误蔓延.

Python有时可以很好地使这些复杂的导入工作,并且它们何时能够工作和不工作的规则根本不直观.一般规则是从xxx.yyy导入zzz可以比导入xxx.yyy更加宽容,然后是xxx.yyy.zzz.在后一种情况下,解释器必须在检索xxx.yyy.zzz时完成将yyy绑定到xxx命名空间,但在前一种情况下,解释器可以在顶层包之前遍历包中的模块命名空间已完全设置.

所以对于这个例子,真正的问题是a.py中的裸导入这很容易修复:

from level1.level2.base import Base

class A(Base): pass

始终使用相对导入是强制使用from … import的一种好方法,原因很简单,相对导入在没有from’的情况下不起作用.要使用上面示例的相对导入,level1 / level2 / a.py`应包含:

from .base import Base

class A(Base): pass

这打破了有问题的导入周期,其他一切正常.如果导入的名称(例如Base)在没有以源模块名称作为前缀时过于混乱,则可以在导入时轻松地重命名:

from .base import Base as BaseModel

class A(BaseModel): pass

虽然这解决了当前的问题,但如果包结构变得更复杂,您可能需要考虑更普遍地使用相对导入.例如,level1 / level2 / __ init__.py可以是:

from .base import Base

from .a import A

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值