Earlier, in Section 19.2.5, we have seen that one of the powerful properties a software piece can have is to be reusable. We also concluded that the more flexible it is, the more general and thus reusable it will be. Let us now summarize some mechanisms in object-oriented programming that help in achieving more flexibility.
Some of these techniques, mainly inheritance, are available in Python, other, such as genericity and overloading, are not, or in a restricted way.
If you want a method to behave differently according to the parameters, you must either create subclasses or write the code to analyze the parameters yourself. In Example 19.5, there is an example a method dealing with different types of parameters, that are manually handled.
Example 19.5. Curve class: manual overloading
def __getitem__(self, key):
"""
Extended access to the curve.
c[3]
c['toto']
c['x<100']
c['x==y']
"""
_x = []
_y = []
_result = None
if type(key) is ListType:
_x = key
_x.sort()
_y = self.y(_x)
_result = Curve(zip(_x, _y))
elif type(key) is SliceType:
_x = self._range_x(key.start, key.stop)
_y = apply(self.y, _x)
if _x and _y:
_result = Curve(zip(_x, _y))
elif self._curve.has_key(key):
_result = self._curve[key]
elif type(key) is StringType:
_x = self._tag_x(key)
if len(_x) > 0:
_x.sort()
_y = self.y(_x)
_result = Curve(zip(_x, _y))
else:
_result = self._getexpr(key)
if _result is not None:
return _result
![]() | Recognizes the argument as a list. |
![]() | Recognizes the argument as a slice. |
![]() | Recognizes the argument as an index. |
![]() | Recognizes the argument as a string, that is going to be further analyzed as a tag name or an expression. |
![]() | Recognizes the argument as a tag name. |
![]() | Recognizes the argument as an expression, such as 'x< y' or 'y>10'. |
Python is not able to do this analysis automatically, because it is dynamically typed. You do not have any mean to specify the type of the parameter. In a language providing static typing and full method overloading, i.e also within the same class, you could have several __getitem__ definitions that would look like:
def __getitem__(self, key: List):
...
def __getitem__(self, key: Slice):
...
def __getitem__(self, key: String):
...
As you can notice, this is of course not valid Python
code, since there is no possibility to define the type of
a parameter in Python.