© Paul Gerrard 2016
Paul GerrardLean Python10.1007/978-1-4842-2385-7_6

6. Object Orientation

Paul Gerrard
(1)
Maidenhead, Berkshire, UK
 

What Is Object Orientation1 ?

The professional approach to programming has shifted away from designing systems with a hierarchy of features defined in functions toward an object-oriented (OO) approach. We look here at how Python fully supports object orientation.
In this book, we can only give a flavor of how objects are used. We work through an example and introduce some of the most basic concepts. We use some OO concepts in our explanation so you need a basic understanding of OO to work through this section.
In OO design, systems are composed of collaborating sets of well-defined objects. Rather than one piece of functionality making use of another function, one object sends a message to another object to achieve some goal. The message is in effect a function call, but the function (usually called a method) is associated with the object in question and the behavior of the method depends on the nature of the object.
You have already come across objects in many places. In fact, in Python everything is an object; we just haven’t elaborated on this OO view of the world. For example, a string has several useful methods:
newstring = text.upper()  # uppercase the string
newstring = text.lower()  # lowercase the string
newstring = text.split(' ')  # split lines
The string functions return a new variable—the new object—sometimes called an instance 2 of the string class. The object (the new string) is the output of the method called on the original string.
In more complex objects, the object itself has attributes or properties that we can set and get.3 We might create a person object, for example. The functions or methods that a person object allows would include a new or create method as well as various set methods and get methods; for example:
fred=customer(name='Fred') # create new customer
fred.setAge(49)            # change age to 49
fred.gender='Male'         # Fred is male
cdate=fred.getCreateDate() # get the creation date
age = fred.getAge()        # get Fred's age
del fred                   # Fred no longer wanted L
In the preceding example, you can see there were some get and set methods that get and set Fred’s attributes, like his age and creation date. His age and creation date cannot be accessed directly except through these simple get and set functions.
There was one attribute that could be examined directly, though: fred.gender. It wasn’t a method because there were no parentheses associated when we referenced it. We can access that attribute directly and we can set it just like any other variable through an assignment.

Creating Objects Using Classes

In our Python code, a new object is defined by referring to a class . In the same way that we can create an int(), a list(), and str() types, we can define our own more complex objects using a class definition.
A class definition is a template for a new object. It defines the mechanism and data required to create a new instance of that class, its attributes (both private and public), and the methods that can be used to set and get attributes or change the state of the object.
Note that we are not recommending this as a perfect implementation of a person class; it is just an example to illustrate the use of class definitions, object attributes, and methods.
The module that defines the person class is people.py:
1   from datetime import datetime
2  
3   class person(object):
4       "Person Class"
5       def __init__(self,name,age,parent=None):
6           self.name=name
7           self.age=age
8           self.created=datetime.today()
9           self.parent=parent
10          self.children=[]
11          print('Created',self.name,'age',self.age)
12  
13      def setName(self,name):
14          self.name=name
15          print('Updated name',self.name)
16  
17      def setAge(self,age):
18          self.age=age
19          print('Updated age',self.age)
20          
21      def addChild(self,name,age):
22          child=person(name,age,parent=self)
23          self.children.append(child)
24          print(self.name,'added child',child.name)
25  
26      def listChildren(self):
27          if len(self.children)>0:
28              print(self.name,'has children:')
29              for c in self.children:
30                 print('  ',c.name)
31          else:
32              print(self.name,'has no children')
33      
34      def getChildren(self):
35          return self.children
  • Line 1 imports the datetime and printing modules we’ll need later.
  • Line 3 starts the class definition. We have used the generic object type, but classes can subclassed and inherit the attributes and methods of another parent class.
  • Lines 5 through 11 creates a new object. Python doesn’t need a “new” method: When the object is created, Python looks for an __init__() method to initialize the object. The arguments passed through the creation call are used here to initialize the object attributes.4
  • The two methods in lines 13 through 19 update the object attribute’s name and age.
  • In lines 21 through 24, the addChild method creates a new person who is a child of the current person. The children objects are stored in an attribute children, which is a list of the person objects for each child.
  • In lines 26 through 32, the listChildren method prints out the names of the children for this person.
  • In lines 34 and 35, the getChildren method returns a list containing the children of this person.
Note
Class methods would not normally print information messages to describe their behavior. This instrumentation code in the class is there to show what's going on inside.
We wrote a program that tests the person class called testpeople.py. To show the output inline, I pasted the code into the interpreter. The embedded comments should explain what’s going on.
1   >>> from people import person
2   >>> #
3   ... #   create a new instance of class person
4   ... #   for Joe Bloggs, age 47
5   ... #
6   ... joe=person('Joe Bloggs',47)
7   Created Joe Bloggs age 47
8   >>> #
9   ... #   use the age attribute to verify
10  ... #   Joe's age
11  ... #
12  ... print("Joe's age is",joe.age)
13  Joe's age is 47
14  >>> print("Joe's full name is ",joe.name)
15  Joe's full name is  Joe Bloggs
16  >>> #
17  ... #   add children Dick and Dora
18  ... #
19  ... joe.addChild('Dick',7)
20  Created Dick age 7
21  Joe Bloggs added child Dick
22  >>> joe.addChild('Dora',9)
23  Created Dora age 9
24  Joe Bloggs added child Dora
25  >>> #
26  ... #   use the listChildren method to list them
27  ... #
28  ... joe.listChildren()
29  Joe Bloggs has children:
30     Dick
31     Dora
32  >>> #
33  ... #   get the list variable containing Joe's children
34  ... #
35  ... joekids=joe.getChildren()
36  >>> #
37  ... #   print Joe's details.
38  ... #   NB the vars() function lists the values
39  ... #   of the object attributes
40  ... #
41  ... print("** Joe's attributes **")
42  ** Joe's attributes **
43  >>> print(vars(joe))
44  {'age': 47, 'children': [<people.person object at 0x021B25D0>, <people.person object at 0x021B2610>], 'name': 'Joe Bloggs', 'parent': None, 'created': datetime.datetime(2014, 4, 4, 8, 23, 5, 221000)}
45  >>> #
46  ... #   print the details of his children
47  ... #   from the list we obtained earlier
48  ... #
49  ... print("** Joe's Children **")
50  ** Joe's Children **
51  >>> for j in joekids:
52  ...     print(j.name,'attributes')
53  ...     print(vars(j))
54  ...
55  Dick attributes
56  {'age': 7, 'children': [], 'name': 'Dick', 'parent': <people.person object at 0x021B2590>, 'created': datetime.datetime(2014, 4, 4, 8, 23, 5, 229000)}
57  Dora attributes
58  {'age': 9, 'children': [], 'name': 'Dora', 'parent': <people.person object at 0x021B2590>, 'created': datetime.datetime(2014, 4, 4, 8, 23, 5, 231000)}
59  >>>
  • Line 1 imports the module we need.
  • Line 6 creates a person by the name of Joe Bloggs.
  • Lines 12 through 15 print Joe Bloggs’s details.
  • Lines 19 through 24 add two children to Joe’s record. Note that the person class adds new person objects for each child.
  • Line 28 calls the joe.listChildren() method to list the details of Joe’s children.
  • Line 35 uses the joe.getChildren() method to obtain a list of Joe’s children objects.
  • Lines 41 through 43 use the vars() function to collect the attributes of the joe object. You can see all of the variables defined for the object, including a list of Joe’s children.
  • Lines 51 through 53 loop through the joekids list printing the attributes of the children objects.
The preceding narrative gives you a flavor of how OO works in the Python language. OO is a large and complex topic that requires careful explanation.5
Footnotes
1
Object orientation is a big topic. You can see an overview of OO programming at http://en.wikipedia.org/wiki/Object-oriented_programming .
 
2
When you create a new object from a class definition, that object is sometimes called an instance and the create process called instantiation. We use the word object, though, in our description.
 
3
It is a design choice as to whether we hide attributes and make them available only through methods (private attributes) or expose them to the outside world (public).
 
4
Note that the first argument to all of the methods in the class is 'self', the object itself. This argument is used internally in the class and is not exposed to the code that calls these methods, as you'll see in the test that follows. The "self." attributes are public.
 
5
The Python implementation of OO differs in some respects from other languages such as Java, for example. Python has a rather more “relaxed” attitude to OO, which makes some things easier for the programmer, but does mean that the programmer needs to be a little more careful in his or her coding. It is up to you to decide which approach is best.
 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.195.225