Python language basics 78: composite classes
February 13, 2016 Leave a comment
Introduction
In the previous post we looked at property getters in Python. They are “normal” methods but they have a special purpose, namely to read the values of class level properties. Getters and setters are not as strictly defined as in other popular languages like Java and C# and you’ll come across various solutions for those types of special functions in your Python projects.
In this post we’ll look at composite classes.
Composite classes
What are composite classes? They are classes that have other classes as properties. You can not only have primitive types, like numbers and strings as class properties but other classes as well. Let’s build on our Person class. Here’s a simplified version:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
def describe_me(self):
return "My name is " + self._name + " and I am " + str(self._age) + " years old."
def shout(self, what, how_many_times):
for i in range(0,how_many_times):
print(what)
We now want to add some more properties, like first name, last name, address, mobile number, home number etc. We could supply each of those values through the init function but there’s a more sophisticated solution. Instead of letting the argument list of the init function grow for ever we can group the related properties and organise them in separate classes. We’ll ignore validation in these classes so that they don’t get bloated.
Let’s put the name related properties into a separate class:
class Name:
def __init__(self, first_name, last_name, middle_name):
self._first_name = first_name
self._last_name = last_name
self._middle_name = middle_name
def name(self):
return self._first_name + " " + self._middle_name + " " + self._last_name
We’ll do the same for the Address and Telephone components:
class Address:
def __init__(self, street_name, street_number, postal_code, city):
self._street = street_name
self._number = street_number
self._postal_code = postal_code
self._city = city
def address(self):
return str(self._number) + " " + self._street + " " + self._postal_code + " " + self._city
class Telephone:
def __init__(self, home, office, mobile):
self._home_number = home
self._office_number = office
self._mobile_number = mobile
def home_number(self):
return self._home_number
def mobile_number(self):
return self._mobile_number
def office_number(self):
return self._office_number
Finally here’s the revised Person class:
class Person:
def __init__(self, name, address, telephone, age):
self._name = name
self._address = address
self._telephone = telephone
self._age = age
def describe_me(self):
return "My name is " + self._name.name() + ", I am " + str(self._age) + " years old, my address is " + self._address.address() \
+ " and you can reach me at home on " + self._telephone.home_number()
def shout(self, what, how_many_times):
for i in range(0,how_many_times):
print(what)
That funny “\” character is used for line breaks to indicate that the code continues on the next line. This is to avoid very long code lines.
Here’s an example of using the new Person class:
from domains import *
name = Name("John", "Smith", "William")
telephone = Telephone("34535", "345345", "65765754")
address = Address("New street", 34, "324 56", "Los Angeles")
person = Person(name, address, telephone, 30)
print(person.describe_me())
…which prints…
My name is John William Smith, I am 30 years old, my address is 34 New street 324 56 Los Angeles and you can reach me at home on 34535
Read the next part here.
Read all Python-related posts on this blog here.