2.5.2. Object oriented programming¶
Object oriented programming is fairly common in Python, and we’ve used it pretty much from the beginning. See for example this code:
with open('test.txt', 'w') as f:
for i in xrange(5):
f.write("%f %f\n" % (0.2, 0.5))
Here, “f” is a file object and “write” is a member function of the file class.
In general, in many languages including Python, if you call a function such that the function syntactically appears to “belong” to a variable, like with “f.write()”, then you’re probably calling a member function of a class.
2.5.2.1. Defining your own data types¶
In Python, data types are defined using the “class” keyword:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class A(object):
def __init__(self, foo):
self.foo = foo
def add_one(self):
self.foo += 1
def call_me(self):
print 'A called - my foo is: ' + str(self.foo)
obj = A(42)
obj.call_me()
obj.add_one()
obj.call_me()
|
Let’s go through this line by line:
- Line 1: We define a class named A. At a high level, a class is a data type, describing data types and functions common to the class.
- Line 2: We define the init function, or constructor: a function that will be automatically called when an object of this class is created.
- Line 3: The constructor will create a member variable named foo - a variable that’s contained within the object.
- Line 5-6: We define a member function - a function that’s part of a class.
- Line 8-9: This member function produces some output and also uses the member variable value.
- Line 11: We create (or instantiate) one object of class A. Class A has a constructor that requires one parameter: we pass in 42.
- Line 13: We call the member function “call_me” for class A.
- Line 14: We call the member function “add_one” for class A.
- Line 15: We call the member function “call_me” for class A.
Executing this will output:
$ python2 cl1.py
A called - my foo is: 42
A called - my foo is: 43
2.5.2.1.1. Duck typing revisited¶
Here’s a bit larger example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class A(object):
def __init__(self, foo):
self.foo = foo
def add_one(self):
self.foo += 1
def call_me(self):
print 'A called - my foo is: ' + str(self.foo)
class B(object):
def call_me(self):
print 'B called'
my_objects = [A(42), B()]
for o in my_objects:
o.call_me()
|
Let’s go through this line by line:
- Lines 1-10: As in the example above.
- Line 11: We define another class named B.
- Line 12-13: We define a member function for class B - with the same name as we did for class A.
- Line 15: We define a list with two elements, and create (or instantiate) one object of each class; one of class A, one of class B. Class A has a constructor that requires one parameter: we pass in 42.
- Line 17: We iterate through our list.
- Line 18: We call the member function “call_me” for each element in the list, i.e. once for our object of class A, once for our object of class B.
Executing this will output:
$ python2 cl.py
A called - my foo is: 42
B called
We see an example of duck typing here: while classes A and B technically have nothing to do with each other, they do share the same interface, namely calling the function “call_me”. We also see that the classes in Python are more powerful than the structs in C: in Python we can combine multiple variables in one object, but in addition we can have member functions and use these to define an interface on interacting with the data.