On Sun, 26 Jun 2005 17:58:11 -0400, George Sakkis wrote
(in article <[EMAIL PROTECTED]>):

> "Paul McGuire" <[EMAIL PROTECTED]> wrote:
> 
>> Lee C -
>> 
>> Here is a technique for avoiding the if-elseif-elseif...-else method
>> for building objects.  It is a modified form of ChainOfResponsibility
>> pattern, in which you have a collection of factory methods that all
>> have a common signature, or a collection of Factory classes that all
>> implement a "makeObject" method.  These common methods probably take a
>> string, and return a generic object.  Fortunately, such type
>> flexibility is *very* easy in Python. :)
>> 
>> Example:
>> I want to convert individual strings to native data types.  I want to
>> detect integers, reals, complex numbers, and booleans (indicated by
>> 'True' or 'False').  This is kind of similar to a parsing problem, but
>> it could also be used for deserializing or unpickling data of an
>> unknown original type.
>> 
>> Note the special treatment I have to go through with boolean values - I
>> needed to write a special makeBool routine, since Python will take any
>> non-empty string to be True, when what I want is 'True' to yield true
>> and 'False' to yield false.
>> 
>> Hope this gives you some alternative ideas to your cascading if's.
>> 
>> -- Paul
>> 
>> 
>> def makeBool(s):
>> if s in ('True','False'):
>> return s == 'True'
>> raise ValueError
>> 
>> converters = [ int, float, complex, makeBool, str ]
>> 
>> def makeObject(stringVar):
>> for conv in converters:
>> try:
>> val = conv(stringVar)
>> except Exception:
>> continue
>> else:
>> break;
>> return val
>> 
>> def test(s):
>> val = makeObject(s)
>> print s, val, type(val)
>> 
>> test('1')
>> test('1.0')
>> test('1+2j')
>> test('1+0j')
>> test('True')
>> test('False')
>> test('A')
>> 
>> prints:
>> 1 1 <type 'int'>
>> 1.0 1.0 <type 'float'>
>> 1+2j (1+2j) <type 'complex'>
>> 1+0j (1+0j) <type 'complex'>
>> True True <type 'bool'>
>> False False <type 'bool'>
>> A A <type 'str'>
> 
> Nice technique. Something that needs to be pointed out is that the
> order of the converters *is* important; int takes precedence over
> float, which take precedence over complex and bool takes precedence
> over string. More succinctly:
> { int -> float -> complex }
> { bool -> str             }
> In general the converters will form a strict partially ordered set, so
> the list of converters should be a topological sort of the respective
> DAG.
> 
> George
> 
> 

Ah yes, there is more than one way to skin a cat :~) and your samples are 
helping me get a better grasp of both Python and OOP in such.  I find both 
Bengt's and Paul's variation on a theme understandable (I must be making 
progress :~) and interesting.  I must admit that I did have to look twice at 
Bengt's clever little slice on 'an' though.  

I had already worked my way through <a 
href="http://fraca7.free.fr/blog/index.php?2005/02/28/2-design-patterns-part-
i---chain-of-responsibility">this</a> though, so they were that much more 
understandable.  

 Actually, I'm using a superclass as a factory, similar to Steve B's example 
(as modified by someone I can't find the name of).  The difference is that my 
criteria does not map easily to class names so I have the verbose decision 
sequence in my superclass.  Of course, if I want to get really fancy,  I 
could use the COR pattern within such.

I'm making more hay out of this one little pasture than I expected (i.e. 
increasing my understanding) thanks to all of you.  I'm going to have to 
start writing down names (rather than rely on this ol head) so I can properly 
thank everyone - like those clarifying other examples.  

At some point I'll put up the original top-down and OO refactored versions of 
my little utility in the hope that I will learn even more from criticism of 
my efforts.  The "new deal" top-down structured programming encountered in my 
continuing post grad work at BU in the 1960s was easier to get a solid handle 
on ;')  

Much appreciated,

Lee C

"Wonder rather than doubt is the root of knowledge." --Abraham Joshua Heschel


-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to