Getters and setters

If we assume that people are using this script to do work, but we want to improve upon it by adding new features, such as preventing a temperature less than absolute zero, we need to make it easy for our users to deal with the change.

This is where getter and setter methods come in. Normally, the direct access to temp would be hidden behind these methods, so that the only interface to interact with temp would require a method call, as shown in following screenshot:

Getter and setter methods

On line 90, we have rewritten the Fahrenheit class to include a getter and setter; these are the only ways to interact with the temp variable. In addition, we have renamed it to _temp; the leading underscore tells Python to treat it as a private variable that should only be accessed by this class. (This isn't completely true, but the reasons why Python doesn't have truly private variables is beyond the scope of this book.)

A new instance is created on line 91, and we retrieve the default temperature value on line 92. When we attempt to set the temperature to a value below the absolute value, we receive an error, as desired (line 93).

Lines 94 and 95 set a more realistic temperature and verify it was set, respectively. If we attempt to get the value of temp the old-fashioned way (line 96), we receive an error, because that variable is no longer directly accessible that way. If we recognize the private naming convention and provide a leading underscore (line 97), we can still access the temperature directly. However, the purpose of a private variable is to prevent direct access like this.

The problem of using getter and setter methods like this is the issues it causes for users of the program. They now have to change all their programs to use the getter and setter methods, rather than direct variable access. It may be simple with this script, but imagine if we did this with a larger program that had tens or hundreds of getter/setter methods; we have essentially broken any backwards compatibility with our previous versions.

The Python version of getters and setters is property. Simply put, a property uses built-in functionality to perform getter/setter methods without requiring the knowledge of specific method names. All changes to the code are internal to the program, so users don't have to worry about the implementation.

The following screenshot demonstrates using the Python property attribute:

Using Python @property

The previously used class is slightly modified on line 5. Note that the __init__() method changed from calling a set_temp() method to simply assigning the temp argument to the self.temp variable. Also, the to_celsius() method uses the variable directly, rather than calling the get_temp() method.

The @property decorator is a Python built-in function that tells Python that the following method defines the getter functionality for a variable. In this case, all we do is return the value of self.temp when the variable is referenced elsewhere.

Decorators in Python are any callable objects that can modify a function or method. They allow some additional functionality similar to other languages, such as declaring a method as a class or static method. Decorators allow you to wrap a function or method in another function that can add new functionality, modify arguments, or results, and so on. You write decorators one line above the function definition, beginning with an "at" sign (@).

The@temp.setter decorator works with the @property decorator to define the setter functionality for the indicated variable. Functionality of the following method is no different than the original setter method; it's just wrapped within the decorator so Python knows which variable it applies to.

We make a new instance on line 6, and confirm that the temperature argument was correctly assigned on line 7. Note that no special methods were called, nor was the private name _temp required to be used. While the private name is used within the class, the property handles the access to it.

Lines 8 and 9 show off the setter and getter functionality inherent with the property. Again, nothing special has to be done in terms of method or variable calls. The new value is assigned like a normal variable assignment, and the value is returned just by asking for it.

Line 10 shows that the to_celsius() method works the same as before. It uses the property abilities to get the value of temperature and doesn't require calling a getter method.

When first making a program, it's probably natural to write getter/setter methods. However, as part of the refactoring process, changing those to properties is advisable due to the simplicity they provide when working with variables, as well as making life easier for users of your software.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.34.62