使用装饰器在__all__中添加名称是个好习惯吗?
在Python中,这样做算不算好习惯呢?(来自 Active State Recipes -- Public Decorator)
import sys
def public(f):
"""Use a decorator to avoid retyping function/class names.
* Based on an idea by Duncan Booth:
http://groups.google.com/group/comp.lang.python/msg/11cbb03e09611b8a
* Improved via a suggestion by Dave Angel:
http://groups.google.com/group/comp.lang.python/msg/3d400fb22d8a42e1
"""
all = sys.modules[f.__module__].__dict__.setdefault('__all__', [])
if f.__name__ not in all: # Prevent duplicates if run from an IDE.
all.append(f.__name__)
return f
public(public) # Emulate decorating ourself
大致的想法是定义一个装饰器,这个装饰器可以接收一个函数或类,然后把它的名字添加到当前模块的 __all__
中。
4 个回答
1
我觉得这个问题有点主观,但我喜欢这个想法。我通常在我的模块中使用 __all__
,不过有时候我会忘记把一个新函数加进去,而这个函数本来是我想让它成为模块公共接口的一部分。因为我通常是按名称导入模块,而不是使用通配符,所以我不会注意到这个错误,直到我团队里的其他人(他们用通配符语法来导入整个模块的公共接口)开始抱怨。
注意:问题的标题有点误导,正如其他人已经在回答中提到的那样。
17
在Python中,更常见的做法是通过在函数名前加一个下划线来标记这些私有函数,也就是说,这些函数是私有的,不应该被外部直接使用:
def public(x):
...
def _private_helper(y):
...
这样做会让更多人觉得熟悉(而且这种写法也是Python语言支持的:即使你不使用 __all__
,_private_helper
这个函数也不会被导出),比起你用的 public
装饰器来说,更容易被大家接受。
8
是的,这样做是个好习惯。这个装饰器让你可以在定义函数或类的时候就说明你的意图,而不是在之后再说。这样可以让你的代码更容易理解。
@public
def foo():
pass
@public
class bar():
pass
class helper(): # not part of the modules public interface!
pass
注意:虽然 helper
仍然可以通过 modulename.helper
被模块的用户访问,但它不会通过 from modulename import *
这种方式被导入。