Python: 包中的“私有”模块
我有一个包叫做 mypack
,里面有两个模块 mod_a
和 mod_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模块包装时,建议在模块名前加下划线;比如 _socket
和 socket
。
20
我决定的解决办法是创建一个叫做'private'的子包,把我想要隐藏的所有模块放在里面。这样一来,这些模块就被藏起来了,让mypack
的模块列表看起来更整洁,也更容易理解。
对我来说,这样做也不显得不符合Python的风格。