As you develop more sophisticated modules and packages, you will often find that your code needs to be configured in some way before it can be used. For example, imagine that you're writing a package that uses a database. To do this, your package needs to know which database engine to use, the name of the database, and the username and password to use to access that database.
You could hardwire this information into your program's source code, but doing this is a very bad idea, for two reasons:
These database access credentials are an example of package configuration—information that your package needs before it can run but which you don't want to build into your package's source code.
If you are building an application rather than a standalone module or package, your configuration task is much simpler. There are modules in the Python Standard Library that can help with configuration, for example, configparser
, shlex
, and json
. Using these modules, you can store configuration settings in a file on disk, which the end user can edit. When your program starts, you load those settings into memory and access them as needed. Because the configuration settings are stored externally to your application, users won't have to edit your source code to configure the program, and you won't be exposing sensitive information if your source code is published or shared.
When writing modules and packages, however, the file-based approach to configuration is much less convenient. There's no obvious place to store a package's configuration file, and requiring configuration files at a particular location is going to make your module or package harder to reuse as part of a different program.
Instead, configuration for a module or package is usually done by supplying parameters to your module or package's initialization function. We saw an example of this in the previous chapter, where the quantities
package required you to supply a locale
value when initializing the package:
quantities.init("us")
This passes the job of configuration back to the surrounding application; the application can make use of a configuration file, or any other configuration scheme it likes, and it is the application that supplies the package's configuration settings when the package is initialized:
This makes things easier for the package developer as all the package needs to do is remember the settings it has been given.
While the quantities
package only used a single configuration setting (the name of the locale), it is common for packages to use many settings. A very convenient way of supplying the configuration settings for a package is to use a Python dictionary. For example:
mypackage.init({'log_errors' : True, 'db_password' : "test123", ...})
Using a dictionary in this way makes it easy to support default values for your package's configuration settings. The following Python snippet shows how a package's init()
function can accept configuration settings, supply default values, and store the settings in a global variable so that it can be accessed when needed:
def init(settings): global config config = {} config['log_errors'] = settings.get("log_errors", False) config['db_password'] = settings.get("db_password", "") ...
Using dict.get()
in this way, you retrieve the setting if one has been supplied, while providing a default value to use if the setting isn't specified. This is an ideal way of handling configuration within a Python module or package, making it simple for users of your module or package to configure it as required, while still leaving the details of how and where the configuration settings are stored up to the application.
3.128.200.71