See All Titles |
![]() ![]() PolymorphismThe concept of polymorphism doesn't really apply to Python objects because Python doesn't offer type declaration. This concept (having a function or method work for multiple argument types) is something you get for free with Python because of the dynamic typing. It does exist, but you don't usually explicitly code for it. When handling an obj.method expression, the meaning of method depends on the type, or class, of the object obj. Python doesn't know what type of object implements an interface until the program is running. This feature is called runtime binding. Python variables are typed, just not explicitly so. They are typed implicitly as the program uses them. For instance, if a program invokes abs(x), it doesn't make sense for x to be any object but a number. Therefore, the variable x is informally typed. The capability of dealing with objects at different levels of abstraction is one of the most important features of object-oriented programming and a very important part of Python. The next example shows how you can use just one function to implement poly morphism in Python. C++ refers to this variety of polymorphism as method overloading. >>> class polymorph: def handle_int(self, argint): print '%d is an int'% argint def handle_str(self, argStr): print '%s is a string'% argStr def handle(self, arg): if type(arg) == type(1): self.handle_int(arg) elif type(arg) == type(''): self.handle_str(arg) else: print "%s is not a string nor an integer" % arg >>> p = polymorph() >>> p.handle(10) 10 is an integer >>> p.handle("Albatross!!") Albatross!! is a string The following code implements a class that does not work because the program tries to apply the general concept of polymorphism. This is a very common mistake that always catches programmers who don't know this concept doesn't exist in Python. Note that we try to define two different implementations of the same method (see lines 3 and 6). Right below this sample of code, you can see a traceback message that is provided by the interpreter when we try to run it. 1:>>> ## Beginning of a Python class THAT DOES NOT WORK 2: 3:>>> class Polimorpherror: 4: def __init__(self): 5: print 'No arguments!' 6: def __init__(self, args): 7: print 'One argument!' 8: self.args = args 9: 10:>>> ## End of a python class THAT DOES NOT WORK 11: 12:>>> x = Polimorpherror() >>> x = Polimorpherror() Traceback (innermost last): File "<stdin>", line 1, in ? TypeError: not enough arguments; expected 2, got 1 You cannot do method overloading as shown in the previous example. The next example presents a suggestion for the correct way to implement a solution for this problem. >>> class Polimorpherror: def __init__(self, args=None): if args == None: print 'No arguments!' if args == 1: print 'One argument!' self.args = args The behavior of overloaded functions and methods is better implemented in Python using default arguments or by explicitly looking at the types of the arguments passed into the function. If you have a class for which you need to specify both a default constructor and a constructor that takes initial values of state as arguments, I suggest that you do so by transporting default arguments to the __init__ method. >>> class Animal: def __init__(self, name = "Parrot"): self.name = name def printAnimal(self): print self.name >>> p = Animal() >>> p.printAnimal() Parrot >>> p = Animal("Monkey") >>> p.printAnimal() Monkey If you want to initialize a variable but you don't want to enforce an object type, you can use the None type. >>> class Animal: def __init__(self, name = None): self.name = name def printAnimal(self): print self.name
|
Index terms contained in this sectionbindingruntime implementing polymorphism 2nd initializing variables method overloading 2nd object-oriented programming (OOP) polymorphism overloading method 2nd polymorphism programming object-oriented (OOP) polymorphism runtime binding typed variables variables initializing typed |
© 2002, O'Reilly & Associates, Inc. |