使用装饰器向__all__添加名称是一个好习惯吗?

时间:2011-06-01 18:41:16

标签: python coding-style

这是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 个答案:

答案 0 :(得分:17)

在Python中执行此操作的更惯用的方法是将私有函数标记为私有,方法是使用下划线开头:

def public(x):
      ...


def _private_helper(y):
    ...

更多人会熟悉这种风格(语言也支持这种风格:即使您不使用_private_helper)也不会导出__all__而不是public装饰器

答案 1 :(得分:6)

是的,这是一个很好的做法。这个装饰器允许您在功能或类定义中陈述您的意图,而不是直接在之后。这使您的代码更具可读性。

@public 
def foo():
    pass 

@public 
class bar():
    pass

class helper(): # not part of the modules public interface! 
    pass

注意:<{strong> helper仍由modulename.helper模块的用户访问。它只是没有导入from modulename import *

答案 2 :(得分:1)

这不会自动为__all__添加名称,它只是允许您通过使用@public进行装饰来向所有人添加功能。对我来说似乎是一个好主意。

答案 3 :(得分:1)

我认为这个问题有点主观,但我喜欢这个主意。我通常在模块中使用__all__,但有时我忘记添加一个新功能,我打算将其作为模块公共接口的一部分。由于我通常按名称而不是通配符导入模块,因此在我的团队中的其他人(使用通配符语法导入模块的整个公共接口)开始抱怨之前,我没有注意到错误。

注意:问题的标题具有误导性,因为其他人已经在答案中注意到了。