user200783
user200783

Reputation: 14346

How to structure a Python module to limit exported symbols?

I am writing a Python module whose purpose is to export a single data structure. I believe this means my module should export a single symbol (e.g. foo), with all its other symbols being underscore-prefixed.

Generating the data structure takes a fair amount of code - how should I structure the module to ensure that no symbols within this code are exported without a prefix? Two possible approaches are:

  1. Put the generation code at the top-level, being careful to use underscores throughout, e.g.:

    _bar = ...
    for _i in ...:
        _bar.append(...)
    
    foo = [_bar, ...]
    
  2. Put the generation code within a function which returns the data structure. This requires only the function name to use an underscore. For example:

    def _generate_foo():
        bar = ...
        for i in ...:
            bar.append(...)
        return [bar, ...]
    
    foo = _generate_foo()
    

Is either of these approaches considered better? Or, is there another way to structure this module which would be preferred?

Upvotes: 15

Views: 12832

Answers (2)

BrenBarn
BrenBarn

Reputation: 251478

Note that using the underscore or using __all__ only prevents that name from being imported with from module import * (as documented). It doesn't make the name "private" in any real way. People can still see everything in your module by doing import module and then module._hiddenStuff.

If you want to prevent the symbol from being included in from model import *, you should use __all__. Have the code be whatever you want, but at the top of the module do:

__all__ = ['foo'] # foo being the one thing you do want to export in the wildcard `from module import *`

This has the same effect as using underscores but is much better when you want to exclude most things instead of include them.

Upvotes: 29

bearrito
bearrito

Reputation: 2315

I prefer the function definition approach from a sheer maintainability perspective.

It is also important to remember that we are all consenting adults and it is the users responsibility to use your module in the manner best suited for their use.

The use of the underscore however is supported by PEP-8 and so any _symbols will not be imported by a import *

Upvotes: 0

Related Questions