Python language basics 74: validating class level properties

Introduction

In the previous post we discussed class level properties in some detail. The most important detail we learned is that there are only public members in a Python class. Properties can be added to “self” on the fly within the class but those properties will be visible to all external callers. So all you’ve learnt about access modifiers from your Java course, such as private or public is not applicable in Python.

In this post we’ll explore the basics of validating the values that are sent into the object initialiser. Validation is a large topic so consider this only as a light introduction.

Validation

Before we continue I’d like to come back a little bit to the absence of private variables in Python. It’s important to understand why private variables exist in the first place and why it’s a bit difficult to accept their absence for a staunch C# and Java developer like myself.

Private variables of a class can be likened to your private belongings, such as your wallet. I assume that your wallet has at least some cash in it and possibly a credit card, an ID card and some other important things. You’d probably not leave your wallet in some public place for everyone to search through it. You may be lucky though. It’s possible that no-one takes your wallet and anything in it. However, it’s far from guaranteed.

If you were to model this Wallet class then it may have properties such as cash, ID and credit_card. You’d prefer to control external access to them, right? Just like you’d like to determine how the things enter and leave your wallet. In Java/C#/etc. you’d hide those properties with the private access modifier and write specialised methods that can internally modify the private variables according to some rules.

So if you cannot hide those properties in Python then a second option is to at least validate their initial value within the init function. Validation and the idea of class invariants go hand in hand. Class invariants are the rules of the class. E.g. a price cannot be negative, a person’s name cannot include funny characters like “%&/”, an email address must contain one and only one “@” etc.

Let’s extend the Person class with an _age property:

class Person:

    def __init__(self, name, age):
        self._name = name
        self._age = age

    def whats_your_name(self):
        return self._name

    def describe_me(self):
        return "My name is " + self._name + " and I am " + str(self._age) + " years old."

    def shout(self):
        print("HELLOOOOO")

Example of usage:

person = Person("Elvis", 40)
print(person.describe_me())

…which prints “My name is Elvis and I am 40 years old.”.

However, we can easily provide unacceptable values to the initialisator:

person = Person("", -10)

We can extend the init function and throw an exception if the assigned values are incorrect. Let’s set up the following rules:

  • A person’s name cannot be an empty string
  • A person’s age must be between 0 and 120

Here’s a possible solution:

class Person:

    def __init__(self, name, age):
        if name == "" or str(name).isspace():
            raise ValueError("Person's name must not be empty.")
        if not str(age).isdigit():
            raise ValueError("Age must be a number.")
        if age < 0 or age > 120:
            raise ValueError("Age must lie between 0 and 120.")
        self._name = name
        self._age = age

    def whats_your_name(self):
        return self._name

    def describe_me(self):
        return "My name is " + self._name + " and I am " + str(self._age) + " years old."

    def shout(self):
        print("HELLOOOOO")

Examples where an exception will be raised:

person = Person("", 15)
person = Person("  ", 34)
person = Person("John", 150)

As noted above validation is a large topic. The goal is to check the values sent into the init function so that the object created doesn’t get into an invalid state.

In the next post we’ll look into class level methods.

Read all Python-related posts on this blog here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

2 Responses to Python language basics 74: validating class level properties

  1. Larisa says:

    Hi, Andras!

    I do appreciate your work and wait for next blogs 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: