Python学习笔记番外:包的组织

Python学习笔记番外:包的组织

说实话,Python的代码引用和组织真是一塌糊涂,处处是坑。

我们在执行Python代码的时候,解释器仅仅会将当前工作目录加入sys.path,这就导致如果你的代码结构比较复杂,牵扯到多个子目录,那下面的代码互相引用就很麻烦了。

这还不是最最要命的,最最要命的是你有极大概率会遇到一个beyond top level error

实例

我们先来看我的一个项目代码结构:

image-20210329181846208

项目目录下有三个层级平行的包carrier_pkg\land_pkg\takeoff_pkg。他们中的代码会进行相对引用,比如:

#carrier.py
from abc import ABCMeta, abstractmethod
from ..land_pkg.land_mode import LandMode
from ..takeoff_pkg.takeoff_mode import TakeoffMode

class Carrier(metaclass=ABCMeta):
    def __init__(self):
        self._takeoffMode = None
        self._landMode = None
        self._name=""

看似没毛病,carrier.py的上层目录是项目根目录,而且我们也创建了__init__.py,可以看作一个模块,然后我们通过根目录去引用land_pkg这个子模块,完全说的通。

但是我们一旦执行程序:

image-20210329182349146

这就是我所说的beyond top-level error

我们再在debug窗口查看一下__package__变量:

image-20210329182512710

我们可以看到vikramaditya_carrier.py的所属包是carrier_pkg而非carrier_game_error.carrier_pkg,这就意味着它所属的顶级包是carrier_pkg而非carrier_game_error,所以你要是想通过它去引用项目根目录的其它包,那是做梦。

我不清楚Python为什么会这样设计,明明这种代码结构在PHP或者Java中相当常见,但Python就是表现出了这样古怪的行为。

解决方法

解决方法其实也不是很难,你的顶级包不会到根目录是吧,那我给你多套一层就是了:

image-20210329182941089

比如像上面这样,我们用一个包game_pkg代替项目根目录去包三个子包。

相应的,项目根目录下的test.py引用方式也要稍加修改:

from game_pkg.carrier_pkg.vikramaditya_carrier import VikramadityaCarrier
from game_pkg.carrier_pkg.queen_elizabeth_carrier import QueenElizabethCarrier
from game_pkg.carrier_pkg.nimitz_class_carrier import NimitzClassCarrier
from game_pkg.carrier_pkg.liao_ning_carrier import LiaoNingCarrier
lnCarrier = LiaoNingCarrier()
print(lnCarrier)

其它相对引用的部分不用做任何修改,我们再执行test.py

image-20210329183151453

没有任何问题。

结论

如果你在使用相对引用的时候遇到了beyond top level error,那就多加一层包。

参考资料:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值