OO approach to decision sequence?

George Sakkis gsakkis at rutgers.edu
Sun Jun 26 17:58:11 EDT 2005


"Paul McGuire" <ptmcg at austin.rr.com> 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




More information about the Python-list mailing list