Daniel Arbuckle's Mastering Python
上QQ阅读APP看书,第一时间看更新

The Package structure and interface

For the convenience and sanity of ourselves as the package developers, it's often best to break up the code in a package into many different modules, all of which contain a selection of conceptually related code; this is the package's structure. As a rule of thumb, whenever we think we might want to break the code up into more modules, we probably should go with that impulse.

On the other hand, external code calling on our package is best off when it can take advantage of our code with just one or two import statements that bring in a small number of functions or classes. This is the package's interface, and as a rule of thumb, it should be as minimal as possible, while preserving full functionality, as shown in the following code example:

from example.foo import Foo
from example.bar import BarFactory
from example.baz import Baz

MAIN_BAZ = BAZ()

__all__ = ['Foo', 'BarFactory', 'MAIN_BAZ']

Fortunately, we can have our cake and eat it too!

We could divide our code up however we wish and then import the most useful elements into our init file, which will make them part of the package's route namespace. If all that's in an init file is import statements, we don't need the __all__ variable.

An import* statement will grab the contents of the init file except for variables, starting with an underscore. However, if we define or import anything in the init file that should not be part of the public interface, we can use the __all__ variable to narrow down and control what we export.

Just remember, if we have an all list, it needs to list everything that is part of the package's interface, whether a module, class, function, or variable.

The rest of the modules in the package are still available to be explicitly imported. We're just making it convenient to access the parts that are most likely to be useful outside our own package.

Now we have a good idea of how to name our modules, where to put them so that they become part of our package, and how to give our package a convenient interface. Next, we'll move on to looking at how to make the modules in a package interact with each other.