开发者

Is it a good practice to add names to __all__ using a decorator?

Is this a good practice in Python (from Active State Recipes -- Public Decorator)?

import sys

def pu开发者_StackOverflowblic(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

The general idea would be to define a decorator that takes a function or class and adds its name to the __all__ of the current module.


The more idiomatic way to do this in Python is to mark the private functions as private by starting their name with an underscore:

def public(x):
      ...


def _private_helper(y):
    ...

More people will be familiar with this style (which is also supported by the language: _private_helper will not be exported even if you do not use __all__) than with your public decorator.


Yes, it's a good practice. This decorator allows you to state your intentions right at function or class definition, rather than directly afterwards. That makes your code more readable.

@public 
def foo():
    pass 

@public 
class bar():
    pass

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

Note: helper is still accessible to a user of the module by modulename.helper. It's just not imported with from modulename import *.


I think the question is a bit subjective, but I like the idea. I usually use __all__ in my modules but I sometimes forget to add a new function that I intended to be part of the public interface of the module. Since I usually import modules by name and not by wildcards, I don't notice the error until someone else in my team (who uses the wildcard syntax to import the entire public interface of a module) starts to complain.

Note: the title of the question is misleading as others have already noticed among the answers.


This doesn't automatically add names to __all__, it simply allows you to add a function to all by decorating it with @public. Seems like a nice idea to me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜