Python: 包中的“私有”模块

71 投票
5 回答
38099 浏览
提问于 2025-04-16 03:29

我有一个包叫做 mypack,里面有两个模块 mod_amod_b。我希望这个包和 mod_a 可以被随意导入:

import mypack
import mypack.mod_a

但是,我想把 mod_b 保留给 mypack 自己使用。因为 mod_b 只是用来整理 mypack 内部的代码。

我第一个问题是,在 Python 编程中,像这样有“私有”模块的做法被接受吗?

如果可以的话,我的第二个问题是,怎么才能让使用这个包的人明白我的这个意图呢?我是不是应该在模块名前加个下划线(比如 _mod_b)?还是说创建一个叫 private 的子包,把所有这样的模块放在里面会更好?

5 个回答

11

虽然没有明确的私有关键字,但有一种约定是把私有函数的名字前面加一个下划线。如果前面加两个下划线,其他人就不容易从模块外部调用这个函数。可以参考一下PEP 8中的内容。

- _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
  import *" does not import objects whose name starts with an underscore.

- single_trailing_underscore_: used by convention to avoid conflicts with
  Python keyword, e.g.

  Tkinter.Toplevel(master, class_='ClassName')

- __double_leading_underscore: when naming a class attribute, invokes name
  mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

- __double_leading_and_trailing_underscore__: "magic" objects or
  attributes that live in user-controlled namespaces.  E.g. __init__,
  __import__ or __file__.  Never invent such names; only use them
  as documented.

如果想让整个模块变成私有的,可以不在里面包含__init__.py文件。

63

我在私有模块前面加一个下划线,目的是让用户明白这个模块是私有的。在你的例子中,可以写成 mypack._mod_b

这和PEP8的建议有点类似(但不完全一样),就是当C扩展模块被Python模块包装时,建议在模块名前加下划线;比如 _socketsocket

20

我决定的解决办法是创建一个叫做'private'的子包,把我想要隐藏的所有模块放在里面。这样一来,这些模块就被藏起来了,让mypack的模块列表看起来更整洁,也更容易理解。

对我来说,这样做也不显得不符合Python的风格。

撰写回答