Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a point to setting __all__ and then using leading underscores anyway?

Tags:

python

cpython

I've been reading through the source for the cpython HTTP package for fun and profit, and noticed that in server.py they have the __all__ variable set but also use a leading underscore for the function _quote_html(html).

Isn't this redundant? Don't both serve to limit what's imported by from HTTP import *?

Why do they do both?

like image 665
temporary_user_name Avatar asked Feb 17 '15 22:02

temporary_user_name


3 Answers

Aside from the "private-by-convention" functions with _leading_underscores, there are:

  • Quite a few imported names;
  • Four class names;
  • Three function names without leading underscores;
  • Two string "constants"; and
  • One local variable (nobody).

If __all__ wasn't defined to cover only the classes, all of these would also be added to your namespace by a wildcard from server import *.

Yes, you could just use one method or the other, but I think the leading underscore is a stronger sign than the exclusion from __all__; the latter says "you probably won't need this often", the former says "keep out unless you know what you're doing". They both have their place.

like image 159
jonrsharpe Avatar answered Sep 28 '22 02:09

jonrsharpe


__all__ indeed serves as a limit when doing from HTTP import *; prefixing _ to the name of a function or method is a convention for informing the user that that item should be considered private and thus used at his/her own risk.

like image 31
JoshRomRock Avatar answered Sep 28 '22 00:09

JoshRomRock


This is mostly a documentation thing, in a similar vein to comments. A leading underscore is a clearer indication to a person reading the code that particular functions or variables aren't part of the public API than having that person check each name against __all__. PEP8 explicitly recommends using both conventions in this way:

To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.

Even with __all__ set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.

like image 32
lvc Avatar answered Sep 28 '22 01:09

lvc