Python language basics 73: class level properties

Introduction

In the previous post we looked at initializers and class level properties. We saw how to add the init method to a class so that we could provide the name property. We also added a second init method so that we could still have an “empty” Person object with no preset name. We also discussed how to attach class level fields to “self” on the fly. The value assigned to those properties was available from another class level method.

In this post we’ll consider class level properties. I felt it was important to provide a post dedicated to that topic because the behaviour of class properties in Python is markedly different from other popular OOP languages such as Java, C#, C++ or VB.NET. At least I was quite surprised when I was first exposed to these class related details in Python.

Class level properties

Recall how we added the _name property to the Person class:

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

If you’re coming from the world of a strict OOP language such as Java, C# or VB.NET then you might translate the above Python code into something like this:

private String _name;

public Person(String name)
{
     this._name = name;
}

However, that’s not quite true. First of all “public Person” is a constructor, not an object initializer, but that is not the most interesting detail. The _name variable in the Java example is meant to be visible only within the class, hence the usage of the keyword “private”. The _name variable is private to the Person class. Only the Person class can access it internally. If a Person object is constructed then you cannot directly access its private variables:

Person person = new Person("Mike");
person._name = "Not Mike";

That’s invalid code in Java, it won’t even compile. It’s thank to the protection level “private” in the Person class definition.

There’s none of that in Python. Forget “private”, “public”, “protected” and what you’ve learned about information hiding. The below code is perfectly valid in Python:

person = Person()
person._name = "Mr. President"
print(person.whats_your_name())

That will print “Mr. President”. That’s right, we’ve accessed the class level variable _name from an external caller.

That’s because all properties, initializers and methods declared at the class level are inherently public in Python. You can’t hide them. If you’re coming from Java, C# etc. then that might sound like a crime to you. In Python the customary way to indicate that the external caller should not modify class level properties is by way of the naming convention applied above: the property name starts with an underscore. That’s how users of the class, such as other programmers will know not to mess with them directly. However, keep in mind, that it’s only a signal. It doesn’t provide the same level of protection as the access modifier “private”.

In the next post we’ll look at the basics of validating class level properties.

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.

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 )

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: