代码之家  ›  专栏  ›  技术社区  ›  Crashworks

我如何使Python模块的uuinit_uuuuu.py将其help()委托给同级文件?

  •  2
  • Crashworks  · 技术社区  · 7 年前

    目前我们有一个Python库,它看起来像:

    Jupiter/
      __init__.py
      Ganymede.py
      Callisto.py
    

    Ganymede.py 依次包含函数 Foo() , Bar() ,等等。我们现有的脚本使用这些功能通过

    from Jupiter import Ganymede
    # later in the program...
    Ganymede.Foo()
    

    我想重新组织一些内容,使目录看起来更像

    Jupiter/
      __init__.py
      Ganymede/
        __init__.py
        functions.py
      Callisto/
        __init__.py
        functions.py
    

    不破坏或修改 任何使用木星的脚本。

    如果 Ganymede/__init__.py 使用中描述的导入语法 "The import system" documentation :

    from .functions import *
    

    然后 福() 巴() 最后出现在Ganymede的名称空间中,但是 help() 因为木卫三没有提到它们。

    >>> from Jupiter import Ganymede
    >>> dir(Ganymede)
    ['Bar', 'Foo', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'functions']
    >>> help(Ganymede)
    Help on package Jupiter.Ganymede in Jupiter:
    
    NAME
        Jupiter.Ganymede
    
    PACKAGE CONTENTS
        functions
    
    FILE
        x:\yadda\yadda\ganymede\__init__.py
    

    我真的,真的很想 help(Ganymede) 自动列出所有可用的函数和类。

    我想我可以 execfile("functions.py") 木卫三 但我觉得一定有更干净的方法来做这件事。还是没有?

    我需要在Python2.7.15和3.5.3中都能工作的东西。

    1 回复  |  直到 7 年前
        1
  •  1
  •   abarnert    7 年前

    创建 __all__ 在里面 __init__.py .


    如果你已经有了 __全部__ 在里面 functions.py ,您可以导入它:

    from .functions import *
    from .functions import __all__
    

    如果要将多个模块合并在一起,则必须更详细一些

    from .functions import *
    from .classes import *
    from . import functions
    from . import classes
    __all__ = functions.__all__ + classes.__all__
    

    当然,你也可以说得很清楚:

    from .functions import *
    __all__ = ['spam', 'eggs']
    

    或者,如果要动态构建它:

    from .functions import *
    from . import functions
    __all__ = [name for name in dir(functions) if not name.startswith('_')]
    

    或者(如果你有 __初始年 从许多子模块中收集名称而不执行其他操作)

    from .functions import *
    __all__ = [name for name in globals() if not name.startswith('_')]
    

    或者你可以变得非常聪明,用这种方式做事,例如。, multiprocessing 做:

    from . import functions
    __all__ = [name for name in functions if not name.startswith('_')]
    globals().update({name: getattr(functions, name) for name in __all__})
    

    记住 __全部__ 也会影响到当某人 from Ganymede import * (事实上, that's the main purpose of __all__ ),以及 inspect 以及其他工具报告为包的公共成员。

    我不确定 help 在没有 __全部__ 记录在任何地方(交互式 帮助 一般来说,工作只是简单的记录),与 import 认为是公开的。


    一。好, 多处理 实际上要聪明得多;它不是从子模块中提取属性,而是从该子模块的动态单例属性中提取属性,该属性在主进程和子进程上设置不同,并相应地更改包的一些顶级函数