V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lxy
V2EX  ›  问与答

Python 混乱的 import 问题

  •  
  •   lxy · 2016-09-02 15:51:54 +08:00 · 1764 次点击
    这是一个创建于 3030 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概目录树如下:

    .
    ├── entry1.py
    ├── other_files.py
    └── sub
        ├── entry2.py
        └── pkg
            ├── __init__.py
            ├── mdl_1.py
            └── mdl_2.py
    
    

    sub 是从一个子项目拷贝过来的( git submodule ),主项目要把它整合起来。

    而在 entry2.py 中有引用

    from pkg.mdl_1 import some_class
    

    会提示 unresoleved reference ,原因很明显,有两种方法可以解决

    1 、改成相对引用

    from .pkg.mdl_1 import some_class
    

    2 、改成完整引用

    from sub.pkg.mdl_1 import some_class
    

    但是问题就来了,由于 sub 是子项目,在某些时候要求 sub 可以独立运行( entry2.py ),而在这时以上两种方法均不能使 sub 正确 import 。

    在 so 查到相关问题: http://stackoverflow.com/questions/16981921/relative-imports-in-python-3

    有点区别。历史原因居然是 Guido 的一己之见而搞得这么复杂……

    [所以现在需要一个能够同时兼容主项目和子项目独立运行的简单的 import 方式。]

    9 条回复    2016-09-03 09:21:06 +08:00
    linnchord
        1
    linnchord  
       2016-09-02 15:57:15 +08:00 via Smartisan T1
    不要作为 sub momodule ,作为外部模块引用,系统初始化时增加模块路径到系统路径。
    binux
        2
    binux  
       2016-09-02 16:24:15 +08:00
    用法有误

    1. 如果作为独立的模块, submodule 最好有 setup.py 允许独立 install 。你这样项目的组织结构是错误的。
    2. entry2.py 作为 sub 内模块,不应该允许独立运行。
    3. 如果你非得运行,一可以通过 setup.py 中指定 entry_points ,二可以通过 python -m sub.entry2 运行。
    lxy
        3
    lxy  
    OP
       2016-09-02 16:51:22 +08:00
    @linnchord 这个可以,就是部署麻烦。

    @binux 12 、本来就是先有 sub 独立运行,后来才要整合的。 3 、 verbose

    如果相对引用不需要 Parent module 就好了。若 Guido 不考虑改变一下 import 方式,我觉得这是一个败笔。
    binux
        4
    binux  
       2016-09-02 17:01:03 +08:00
    @lxy 你的 sub 并不是一个正确组织的模块,如果它是正确组织的模块,作为一个整体,单独直接运行一个模块内的任何脚本都是错误的用法。
    lxy
        5
    lxy  
    OP
       2016-09-02 17:24:26 +08:00
    @binux 原本 sub 就可以独立运行并完成任务,并且单独运行的时候, sub 并不从属于主项目(有的机器只需要部署 sub 即可),如果为了去组织一个“正确的模块”而去写一个 sub2 、牺牲代码一致性,实在不值得。
    binux
        6
    binux  
       2016-09-02 17:35:19 +08:00
    @lxy 架构一个正确的模块和能够独立运行又不冲突。。
    linnchord
        7
    linnchord  
       2016-09-02 18:42:36 +08:00 via Smartisan T1
    部署靠 fabric 无痛一键部署 不要手动啊

    @binux 和我是一个意思,只是你是单独部署自定义目录,还是作为标准模块 setup 到系统标准目录。我们以前的实践是把标准、三方模块和自有模块分离的。
    mgna17
        8
    mgna17  
       2016-09-02 19:10:08 +08:00 via Android
    如果是 ImportError 的话,为何不 try 一下呢 😏
    kkzxak47
        9
    kkzxak47  
       2016-09-03 09:21:06 +08:00 via Android
    按照__name__执行不同的 import ?
    一个一个 try ?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1138 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:11 · PVG 07:11 · LAX 15:11 · JFK 18:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.