Choosing Between Getters and Setters or Properties
00:00 Choosing Between Getters and Setters or Properties. In real-world coding, you’ll find a few use cases where getter and setter methods can be preferred over properties, even though properties are generally the Pythonic way to go.
00:13 For example, getter and setter methods may be better suited to deal with situations in which you need to run costly transformations on attribute access or mutation, take extra arguments and flags, use inheritance, raise exceptions related to attribute access and mutation, and facilitate integration in heterogeneous development teams.
00:35 In this section of the course, you’ll dive into these use cases and why getter and setter methods can be preferable to properties. You should avoid hiding slow operations behind a Python property.
00:47 The users of your API will expect attribute access and mutation to perform in a regular manner. In other words, they will expect these operations to happen instantaneously and without side effects.
00:59 Going too far away from that expectation will make your API odd and unpleasant to use, violating the least surprise principle. Additionally, if your users repeatedly access and mutate your attributes in a loop, then their code can involve too much overhead, which may produce huge and unexpected performance issues. In contrast, traditional getter and setter methods make it explicit that accessing or mutating a given attribute happens through a method call. Indeed, your users will be aware that calling a method can take time, and the performance of their code can vary significantly because of that.
01:33 Making these facts explicit in your API can help minimize your users’ surprise when they access and mutate attributes in their code. In short, if you’re going to use a property to manage an attribute, then make sure that the methods behind the property are fast and don’t cause side effects. In contrast, if you’re dealing with slow accessor or mutator methods, then favor traditional getters and setters over properties.
Unlike Python properties, traditional getter and setter methods allow for more flexible attribute access and mutation. For example, let’s say you have a
Person class with a
02:14 This attribute should be constant throughout a person’s lifetime. Therefore, you decide that the attribute will be read-only. However, because there is a thing called human error, you’ll face cases in which someone made a mistake when entering a birth date of a given person.
The setter method takes an extra argument called
force, which allows you to force the modification of a person’s date of birth. Note that traditional setter methods typically don’t take more than one argument.
04:10 One issue with Python properties is that they don’t do well in inheritance scenarios. For example, let’s say you need to extend or modify the getter method of a property in a subclass. In practice, there’s no safe way to do this.
04:24 You can’t just override the getter method and expect the rest of the property’s functionality to remain the same as in the parent class. This issue occurs because the getter and setter methods are hidden inside the property. They’re not inherited independently, but as a whole. Therefore, when you override the getter method of a property inherited from a parent class, you override the whole property including its setter method and the rest of the internal components. An example class hierarchy is seen on-screen.
.name is a read-only property because the setter method of the parent class wasn’t inherited, but was overridden by a completely new property. You didn’t want to do that, so how can you solve this inheritance issue?
07:29 In this regard, traditional getter and setter methods are more explicit than properties. This example seen on-screen doesn’t look like something that can raise an exception. It looks and should behave like a regular attribute assignment.
07:53 In this example, the setter method is more explicit. It clearly expresses the code’s possible behavior. As a rule of thumb, you should avoid raising exceptions from your Python properties unless you’re using a property to provide read-only attributes.
08:08 If you ever need to raise exceptions on attribute access or mutation, then you should consider using getter and setter methods instead of properties. In these cases, using getters and setters will reduce the user surprise and make your code more aligned with common practices and expectations.
08:26 Providing getter and setter methods is common practice in many well-established programming languages. If you’re working on a Python project with a team of developers who come from other language backgrounds, then it’s pretty likely that the getter and setter pattern will look more familiar to them than Python properties. In this kind of team, using getters and setters can facilitate the integration of new developers into the team. Using the getter and setter method can also promote API consistency.
08:53 It allows you to provide an API based on method calls rather than an API that combines method calls with direct attribute access and mutation. Often, when a Python project grows, you may need to migrate the project from Python to another language.
09:08 The new language may not have properties, or they may not behave as Python properties do. In these situations, using traditional getters and setters from the beginning would make future migrations less painful.
Become a Member to join the conversation.