I discovered that the existence and use of metaclasses can save you from a lot code-writing by providing an elegant handle on the process of class creation. I use this in my application, where several interacting servers are instantiated. To elaborate:
Each device instantiates a server class specific to its operation, which is a subclass of (a subclass of...) ulitmately this one BaseServer
class. Now, some device servers need a ThreadedTCPserver
, and some need a SimpleTCPServer
(module: socketserver
). They cannot all derive from the same class because using the ThreadingMixin
overrides the behavior of the SimpleTCPServer
.
To handle this dynamic class configuration, I created a MetaServerType
, which chooses the baseclasses for BaseServer as (SimpleTCPServer,)
or as (ThreadedTCPServer,)
--> producing my desired result of dynamically configured server classes! (Woo hoo)
Now, here comes my question: I would like to use a configuration file where parameters are stored, and these parameters are used by default by the MetaServerType. For example: config.default_loglevel, or config.default_handler etc. And individual servers can be overriden (from command-line or otherwise) according to the metaclass specifications.
It is good design practice to have only one instance of the configuration object being passed through the program-flow? One way to have this is to initialize the config object in the class-body of the metaclass -- but my program-flow begins elsewhere, and this means that the metaclass is called several times thus producing various instances of config. It appears that metaclass is called at import time (?)
So a detailed answer would be very welcome to:
- How can one supply metaclasses with configuration info?
- What is a good way to have a single config instance be passed through the program-flow, to be edited, updated and perhaps eventually written?
- Can the input arguments to metaclass be somehow extended beyond the
Metaclass.__new__(meta, name, bases, attrs)
?- Bonus question: Does this move us one step closer to a finite-state machine (of servers) so that the state (not the instances) can be 'paused' or 'resumed'?