Phillip B Oldham a écrit :
What would be the optimal/pythonic way to subject an object to a
number of tests (based on the object's attributes) and redirect
program flow?

Say I had the following:

pets[0] = {'name': 'fluffy', 'species': 'cat', 'size': 'small'}
pets[1] = {'name': 'bruno', 'species': 'snake', 'size': 'small'}
pets[2] = {'name': 'rex', 'species': 'dog', 'size': 'large'}

What I'd like to do is loop through 'pets', and test each object. Some
of the tests I'd like to perform are:

Is the size 'small' and species not 'dog'?
Is the species 'cat' and name 'fluffy'?
Is the species not 'dog' or 'cat'?

In PHP I'd use a switch statement similar to the following:

foreach( $pets as $pet) {
switch(true) {
case ( $pet['size'] === 'small' && $pet['species'] !== 'dog' ):
// do something
break;
// etc...
}
}

Now, I understand from a bit of googling that python doesn't have a
switch statement, and because of this people rely on python's
polymorphism.

You could also put it the other way round : Python doesn't have a switch statement because peoples use polymorphism !-)

(nb : not that my "reversed" statement is in any way more true than yours - but the fact is that procedural switch statement vs OO polymorphic dispatch is not such a new topic...)

Thats great, but I've yet to come across a decent
example which make a "click".

Any thoughts on how to proceed?

The braindead canonical OO solution would be to make a specific class for each species each implementing it's own version of do_something(). The problem is that it would only dispatch on species, not other attributes (size etc). Which is a inherent limitation of the canonical OO type-based single dispatch mechanism.

A more elaborate canonical OO solution would be to use the visitor pattern to overcome the single dispatch limitation.

A yet more elaborate (but way less canonical) solution is to use predicate-based dispatch (cf Philip Eby's work).

Anyway, and while each dispatch mechanism (from basic branching to complex predicate-based systems) has it's pros and cons, I'd first think twice (or more) about whether my current dispatch problem has some relative stability wrt/ the domain - IOW, it's structurally part of the domain and won't change anytime soon - or if it's one of those ad-hoc short-lived illogical "business rule" that is potentially subject to unpredictable change any other day. Because the appropriate solution really depends on this kind of considerations.

Now wrt/ your concrete example: truth is that, while expressed as a switch statement, it's in fact really a if/elif/.../, since the condition is not a constant (so you don't gain any performance gain from using a switch). So the simplest translation in Python is to use an if/elif/...


for pet in pets:
  if pet['size'] == 'small' and pet['species'] !== 'dog':
     // do something
  elif (other complex condition):
     // etc

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

Reply via email to