[Tutor] Simulating case statement
Hi, I used to use an extended if...elif sequence to instantiate an object and call this object's display method afterwards: if safe['type'] == pages: page = Show.Page(id=safe['id'], start=safe['start'] ...), elif safe['type'] == pages: author = Show.Author(id=safe['id']...) ... page.Display() To improve readability, I changed this code to use a dictionary: valid_types = dict( pages=Show.Page, authors=Show.Author, ... ) page = valid_types[safe_parameters['type']](safe_parameters) page.Display() The problem is that the __init__ methods of the respective classes take a different number of parameters - this is why I pass the whole safe_parameters dictionary. This has a number of drawbacks when instantiating an object in other situations because I cannot use a default for some parameters while passing some others. So I'd like to do pass the parameters individually, based on the class. I know I would need to expand the valid_types dictionary to include the parameters - but how can I pass these one by one? What I came up with is a monster (which does not work anyway): valid_types = dict( pages=dict(klasse=Show.Page, parameters=dict(id=safe['id'], start=safe['start'] ...)) authors=dict(klasse=Show.Author, ...) ... ) page = valid_types[safe_parameters['type']]['klasse'](valid_types['parameters']) page.Display() How can I circumvent the if...elif sequence and have the parameters passed individually at the same time? Thanks for any suggestions, Jan -- Common sense is what tells you that the world is flat. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Simulating case statement
Jan Eden wrote: Hi, I used to use an extended if...elif sequence to instantiate an object and call this object's display method afterwards: if safe['type'] == pages: page = Show.Page(id=safe['id'], start=safe['start'] ...), elif safe['type'] == pages: author = Show.Author(id=safe['id']...) ... page.Display() To improve readability, I changed this code to use a dictionary: valid_types = dict( pages=Show.Page, authors=Show.Author, ... ) page = valid_types[safe_parameters['type']](safe_parameters) page.Display() The problem is that the __init__ methods of the respective classes take a different number of parameters - this is why I pass the whole safe_parameters dictionary. I think if you pass the dictionary as keyword arguments rather than as a single dict you will get what you want. page = valid_types[safe_parameters['type']](**safe_parameters) This syntax means, use safe_parameters to populate the keyword arguments of the function. Any parameters which are not in safe_parameters will be set to their default values, and in other calls you can set the parameters as you like. Here is a simple example: def f1(id='123', value='abc', **kwds): ... print 'id =', id ... print 'value =', value ... def f2(id='345', stuff='nonsense', **kwds): ... print 'id =', id ... print 'stuff =', stuff ... ... params = dict(id=3, value='def') f1(**params) id = 3 value = def f2(**params) id = 3 stuff = nonsense f1() id = 123 value = abc f1(value=34) id = 123 value = 34 The **kwds parameter to the function is needed to allow the extra parameters in the passed dictionary. Otherwise you will get a TypeError: def f3(id='345', stuff='nonsense'): ... print 'id =', id ... print 'stuff =', stuff ... f3(**params) Traceback (most recent call last): File stdin, line 1, in ? TypeError: f3() got an unexpected keyword argument 'value' Kent This has a number of drawbacks when instantiating an object in other situations because I cannot use a default for some parameters while passing some others. So I'd like to do pass the parameters individually, based on the class. I know I would need to expand the valid_types dictionary to include the parameters - but how can I pass these one by one? What I came up with is a monster (which does not work anyway): valid_types = dict( pages=dict(klasse=Show.Page, parameters=dict(id=safe['id'], start=safe['start'] ...)) authors=dict(klasse=Show.Author, ...) ... ) page = valid_types[safe_parameters['type']]['klasse'](valid_types['parameters']) page.Display() How can I circumvent the if...elif sequence and have the parameters passed individually at the same time? Thanks for any suggestions, Jan ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Simulating case statement
Kent Johnson wrote on 27.09.2005: Jan Eden wrote: The problem is that the __init__ methods of the respective classes take a different number of parameters - this is why I pass the whole safe_parameters dictionary. I think if you pass the dictionary as keyword arguments rather than as a single dict you will get what you want. page = valid_types[safe_parameters['type']](**safe_parameters) This syntax means, use safe_parameters to populate the keyword arguments of the function. Any parameters which are not in safe_parameters will be set to their default values, and in other calls you can set the parameters as you like. Here is a simple example: I see. I did not know that I can use a formal parameter **param in calls - thought I could only do so in function definitions: def func(**param): ... func(id=1, stuff='blah') Thanks for that! Jan -- Mac OS X. Because making Unix user-friendly is easier than debugging Windows. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor