Design considerations and tradeoffs

We have a deep hierarchy of packaging techniques. We can simply organize the functionality into defined functions. We can combine the defined functions and their related data into a class. We can then combine related classes into a module. Lastly, we can combine related modules into a package.

When we think of software as a language to capture knowledge and representation, we have to consider what a class or module means. A module is the unit of the Python software construction, distribution, use, and reuse. With rare exceptions, modules must be designed around the possibility of reuse.

In most cases, we'll use a class, because we expect to have multiple objects that are instances of the class. Often – but not always – a class will have stateful instance variables.

When we look at classes with only a single instance, it's not perfectly clear if a class is truly necessary. Standalone functions may be as meaningful as a single-instance class. In some instances, a module of separate functions may be an appropriate design, because modules are inherently singletons.

The general expectation is a simple stateful collection of definitions. A module is a namespace that can also contain some local variables. This parallels a class definition, but lacks the ability to create instances.

While we can create immutable classes (using __slots__, extending NamedTuple, using a frozen @dataclass, or overriding the attribute setter methods), we can't easily create an immutable module. There doesn't seem to be a use case for an immutable module object.

 

A small application may be a single module. A larger application will often be a package. As with module design, packages should be designed for reuse. A larger application package should properly include a __main__ module.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset