If you're using Python 3.4 or newer, you have access to functools.singledispatch
(thanks to PEP 443), which lets you overload functions (preferably unary) much like you would in a language like Java.
If you define your various polyhedra as classes, you can dispatch on their types, like so:
import math from functools import singledispatch class Cube: def __init__(self, x): self.x = x class Cuboid: def __init__(self, x, y, z): self.x = x self.y = y self.z = z class Cylinder: def __init__(self, *, r, h): self.r = r self.h = h # Mark this function as single-dispatchable. @singledispatch def volume(polyhedron): pass # Or throw an exception, or something like that. def _volume_cube(cube): return cube.x ** 3 def _volume_cuboid(cuboid): return cuboid.x * cuboid.y * cuboid.z def _volume_cylinder(cylinder): return math.pi * (cylinder.r) ** 2 * cylinder.h # Register handlers for the types for which you can compute volumes. volume.register(Cube, _volume_cube) volume.register(Cuboid, _volume_cuboid) volume.register(Cylinder, _volume_cylinder)
Now, you can do this:
>>> cube = Cube(4) >>> volume(cube) 64 >>> cuboid = Cuboid(3, 5, 7) >>> volume(cuboid) 105 >>> cylinder = Cylinder(r=2, h=4) >>> volume(cylinder) 50.26548245743669
If you're using a version older than 3.4, you don't really have any good options for this sort of transparent single dispatch (though you could always just backport functools.singledispatch
if you're on an earlier 3.x - it's written in pure Python and I don't think it relies on any new 3.4 features). You could, instead, have a function volume(cube=None, cuboid=None, cylinder=None)
, or volume(polyhedron)
and dispatch on type(polyhedron)
inside the function, or do some magic with **kwargs
.
All that said, I somehow doubt that your book wants you to use functools.singledispatch
- I'd hazard a guess that somebody just copied the problems out of a C++ or Java book without really thinking about it.