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.