Chapter 11. Brief Tour of the Standard Library — Part II 88 Python Tutorial, Release 3.9.5 While those tools are powerful, minor design errors can result in problems that are difficult to reproduce. So, the preferred approach to task coordination is to concentrate all access to a resource in a single thread and then use the $_{queue}$module to feed that thread with requests from other threads. Applications using $_{Queue}$objects for inter-thread communication and coordination are easier to design, more readable, and more reliable. The logging module offers a full featured and flexible logging system. At its simplest, log messages are sent to a file or to$_{sys.stderr}$ : This produces the following output: By default, informational and debugging messages are suppressed and the output is sent to standard error. Other output options include routing messages through email, datagrams, sockets, or to an HTTP Server. New filters can select different routing based on message priority: $_{DEBUG}$,$_{INFO}$ ,$_{WARNING}$ ,$_{ERROR}$ , and$_{CRITICAL}$ . The logging system can be configured directly from Python or can be loaded from a user editable configuration file for customized logging without altering the application. Python does automatic memory management (reference counting for most objects and garbage collection to eliminate cycles). The memory is freed shortly after the last reference to it has been eliminated. This approach works fine for most applications but occasionally there is a need to track objects only as long as they are being used by something else. Unfortunately, just tracking them creates a reference that makes them permanent. The$_{weakref}$module provides tools for tracking objects without creating a reference. When the object is no longer needed, it is automatically removed from a weakref table and a callback is triggered for weakref objects. Typical applications include caching objects that are expensive to create: (continues on next page) >>> import weakref , gc >>> classA : ... def __init__ (self, value): ... self.value=value ... def __repr__ (self): ... return str(self.value) ... >>> a =A(10 ) # create a reference >>> d =weakref.WeakValueDictionary() >>> d['primary'] =a # does not create a reference >>> d['primary'] # fetch the object if it is still alive 10 >>> del a # remove the one reference >>> gc.collect() # run garbage collection right away 0 >>> d['primary'] # entry was automatically removed WARNING:root:Warning:config file server.conf not found ERROR:root:Error occurred CRITICAL:root:Critical error -- shutting down import logging logging.debug( 'Debugging information ') logging.info('Informational message ') logging.warning( 'Warning:config file %s not found','server.conf ') logging.error('Error occurred') logging.critical( 'Critical error -- shutting down ') 11.5 Logging 11.6 Weak References