"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 -- http://mail.python.org/mailman/listinfo/python-list