Managing Attributes in Your Classes
00:00 Managing Attributes in Your Classes. When you define a class in an object-oriented programming language, you’ll probably end up with some instance and class attributes. In other words, you’ll end up with variables that are accessible through the instance, class, or even both, depending on the language. Attributes represent or hold the internal state of a given object, which you’ll often need to access and mutate.
00:39 They provide the behaviors and actions that an object can perform with its internal data and attributes. If you expose your attributes to the user, then they become part of the public API of your classes.
They start using
Circle in their code to create projects and applications. Now suppose that you have an important user that comes to you with a new requirement. They don’t want
Circle to store the radius any longer.
They need a public
.diameter attribute. At this point, removing
.radius to start using
.diameter would break the code of some of your end users. You need to manage this situation in a way other than removing
01:46 Programming languages such as Java and C++ encourage you to never expose your attributes to avoid this kind of problem. Instead, you should provide getter and setter methods, also known as accessors and mutators, respectively.
02:01 These methods offer a way to change the internal implementation of your attributes without changing your public API. Note that getter and setter methods are often considered an anti-pattern and a signal of poor object-oriented design.
02:16 The main argument behind this proposition is that these methods break encapsulation. They allow you to access and mutate the components of your objects. In the end, these languages need getter and setter methods because they don’t provide a suitable way to change the internal implementation of an attribute if a given requirement changes. Changing the internal implementation would require an API modification, which can break your end users’ code.
Here, you create
Point with two non-public attributes,
._y, to hold the Cartesian coordinates of the point at hand. To access and mutate the value of either
._y, you can use the corresponding getter and setter methods.
Note that Python doesn’t have the notion of access modifiers, such as
public, to restrict access to attributes and methods. In Python, the distinction is between public and non-public class members.
If you want to signal that a given attribute or method is non-public, then you have to use the well-known Python convention of prefixing the name with an underscore (
_). That’s the reason behind the naming of the attributes
._y. Note that this is just a convention.
.get_y(), you can access the current values of
._y. You can use the setter method to store a new value in the corresponding manage attribute and confirm that it’s changed.
06:05 This code uncovers a fundamental principle. Exposing attributes to the end user is normal and common in Python. You don’t need to clutter your classes with getter and setter methods all the time, and that sounds good.
06:21 It does raise the question though, how can you handle requirement changes that would seem to involve API changes? Unlike Java and C++, Python provides handy tools that allow you to change the underlying implementation of your attributes without changing your public API. The most popular approach is to turn your attributes into properties.
06:44 Properties represent an intermediate functionality between a plain attribute, or field, and a method. In other words, they allow you to create methods that behave like attributes. With properties, you can change how you compute the target attribute whenever you need to do so.
For example, you can turn both
.y into properties. With this change, you can continue accessing them as attributes. You’ll also have an underlying method holding
.y that will allow you to modify their internal implementation and perform actions on them right before your users access and mutate them.
07:38 The main advantage of Python properties is that they allow you to expose your attributes as part of your public API. If you ever need to change the underlying implementation, then you can turn the attribute into a property at any time without much pain.
Become a Member to join the conversation.