[Python-ideas] Adding an "export" decorator in (e.g.) functools

Peter Otten __peter__ at web.de
Fri May 9 10:45:33 CEST 2014


Bill Winslow wrote:

> Hey guys.
> 
> This is simple pattern I've added to my own "myutils.py" file, which I
> think could see wide use if added to the standard library.
> 
> Simply, it's the following function meant to be used primarily as a
> decorator.
> 
>     def export(func):
>          global __all__
>          if callable(func) and hasattr(func, '__name__'):
>              try:
>                  __all__.append(func.__name__)
>              except NameError:
>                  __all__ = [func.__name__]
>         return func
> 
> 
> Then, instead of having a magic __all__ declaration at the top of a module
> with a list of strings (that may or may not be accurate [of course stdlib
> modules are maintained more rigorously]), people writing libraries can
> instead use the following idiom:
> 
> import stuff_not_meant_to_be_visible
> 
> def _private_func_1(): pass
> 
> def _private_func_2(): pass
> 
> @export
> def public_func_1(): pass
> 
> @export
> def public_func_2(): pass
> 
> 
> Of course, this doesn't actually solve any problem, because programmers
> using best-practice will prepend underscores to private functions and
> define their __all__ properly.
> 
> However I still think this might be worth adding to the stdlib (presumably
> in functools) because
> 
> 1) Readability counts (and explicit is better than implicit): it's easy to
> determine that, other than "well there's no underscore so this is probably
> a public function", that "yes, the library author meant for this function
> to be used".
> 
> 2) Proper maintenance becomes easier. Attaching a small decorator next to
> each public function is easier to remember than remembering to add an
> arbitrary string to an arbitrary global constant. There is also the added
> benefit that renaming/refactoring also doesn't require modifying the magic
> global when you're done.
> 
> 3) It helps encourage best practices, especially among either lazy
> programmers or those new to Python.
> 
> 
> One possible counter argument is that it's not very important/isn't a core
> feature for library inclusion:
> Well, things like an lru_cache or total_ordering aren't core features, but
> they are nice to have, which is why they were added; export would fall
> into the same category.
> 
> What are everyone's thoughts?

I rarely use star imports, and the decorator is mostly noise in my eyes, so 
that's a clear -1 from me. 

I'm mostly posting to suggest an alternative implementation for your 
personal use ;)

def export(f):
    sys._getframe(1).f_globals.setdefault("__all__", []).append(f.__name__)
    return f




More information about the Python-ideas mailing list