Dispatch tables are very handy things when your keys are strings or other literals, but not such a good idea for classes. This is mainly because you lose all potential for catching inherited classes. The proper solution requires isinstance, which in turn requires an if-else ladder, though putting this in the called function isn't as ugly as described. An untested example:
Code:- class A: pass
- class B: pass
- class C(A): pass
- def foo(obj):
- if isinstance(obj, A):
- return fooA(obj)
- elif isinstance(obj, B):
- return fooB(obj)
- else:
- raise TypeError
- def fooA(obj): return "In fooA"
- def fooB(obj): return "In fooB"
Copy Code print foo(A())
should print "In fooA"
print foo(B())
should print "In fooB"
print foo(C())
should print "In fooA"
If you are really set on a dispatch table, you could modify the above with:
Code:- dispatch_table = {
- A: fooA,
- B: fooB,
- }
- def foo(obj):
- for x in dispatch_table.keys():
- if isinstance(obj, x):
- return dispatch_table[x](obj)
- raise TypeError
Copy Code You should get the same results.
This is especially important since you don't know who will subclass the expected classes in the future and call your functions. You will really lose polymorphic potential here. |