[Python-Dev] PEP282 and the warnings framework
Kevin Butler
kbutler@campuspipeline.com
Wed, 15 May 2002 12:32:33 -0600
Fredrik Lundh wrote:
> Kevin Butler wrote:
>
>
>>Subclasses should differ in behavior - if they differ only in data, that data
>>should go into attributes instead. (Yes, this is disputable, but it does tend
>>to simplify designs.)
>
> have you ever used exceptions in python?
Yes.
Have you ever noticed how developers tend to re-use an existing exception
class even when they should define a new subclass?
:-)
Have you ever had to map a 'return code' into an exception hierarchy? Ever
just wrapped the data value as an attribute instead, pushing the switching
behavior off to the exception handlers?
Exception subclasses differing only in class name exist because the language
provides specific support for switching behavior based on the class of a
caught exception. (Python's string-based exceptions separate that behavioral
switching from the exception class hierarchy, but their flat namespace is too
constraining.)
This specific language support pushes the design tradeoff away from the
simplicity of attributes toward the more complex subclass hierarchy, but often
not enough to justify a full mapping of all return codes into classes.
In logging, where there is no language support motivation for additional class
creation, it makes more sense to avoid the subclass creation altogether.
Creating a logger instance with a category value and then sending it lots of
different types messages is easier than creating multiple Message subclasses
for different types of messages and sending them to a single logger instance.
Since you usually want to turn on all message types in a specific area of
code anyway, the single category instance works nicely.
Besides, if you want to build a message-based system on top of a
category-based system, it is easy - mostly just the work you'd have to do
anyway (not tested, yada-yada):
class Message:
logger = Logger( "Message" )
priority = INFO
msg = "Message"
def __init__( self, *args ):
self.args = args
def log( self ):
self.logger.log( self.priority, self.msg, self.args )
Usage:
class MyMessage( Message ):
logger = Logger( "Message.MyMessage" )
priority = WARNING
msg = "MyMessage: Your %s has %s"
MyMessage( "dog", "fleas" ).log()
kb