从pacakge导出python符号的首选方法是什么?

时间:2018-03-22 07:25:30

标签: python packages

我们说我有以下结构:

    • 模块1
      • 的Class1
      • 的Class2

包的用户想要使用class1和class2。

我理解的方式我在__init__.py

中有太多选择
from module1 import class1,class2

这将让用户执行x = pacakge.class1()

之类的操作

或者:

import module1

这将让用户执行x = pacakge.module1.class1()

之类的操作

是否有首选方式?

2 个答案:

答案 0 :(得分:1)

这实际上取决于上下文 - 你的包,模块,类,函数等语义,它们用于什么,它们如何相互关联等等,当然还有包的大小(多少)子包/模块,每个中有多少名称等等 - 所以这里没有一个通用的技术答案。

如果你的模块只是一个实现细节(即避免使用一个单片10 + k源文件),而且从语义POV开始,一些对象(函数,类,等等)真正属于软件包的顶层,然后使用包__init__作为外观,这样用户就不必知道名称的有效定义。

如果您的模块/子包作为一致的命名空间(例如django.dbdjango.forms)有意义,那么您显然希望将它们清楚地区分开来并让用户明确地从中导入它们。

还要记住,一旦子模块或子包名称被公开(它的存在被记录并且客户端代码从中导入),那么它实际上是API的一部分,你不能重命名它/移动它/从中移动东西而不破坏客户端代码。

在最后一种情况下,您仍然可以将模块转换为用作外观的包(使用包__init__),但更改必须(好吧,应该)对客户端代码透明。

作为一般规则:从最简单的实现开始 - 如果是一个简单的单个模块,如果它是一个不需要命名空间的小型lib(只有少数公开名称),或者是一个包含少量& #34;命名空间"用于更大或更少内聚lib的子模块,如果你的模块变得庞大,则使用软件包__init__将它们转换为子包,以将事实隐藏到客户端代码中。

答案 1 :(得分:0)

第二种方法的一个缺点:

  • 如果包中有许多模块,用户必须执行以下操作:

    from package.module1 import *
    from package.module2 import *
    ...
    

    这可能有点烦人。

所以,我认为这是最好的方法:

  1. 我根据上下文将我的包结构化为子包。
  2. 主程序包将导入子包。
  3. Subpackage将导入其所有模块中的所有符号。
  4. 这样,如果我的用户想要使用pacakage的foo功能,他只需执行from pacakge.foo import *并获得foofoo个功能。