Page 1 of 2 Attributes in Python are easy – until you want to do something more than just have an attribute that can reference an object. In this article we look at some of the real world practicalities of using attributes – we look at properties that work with get and set functions. This extract is from my new book with the subtitle "Something Completely Different".
Programmer's Python Everything is an Object Second Edition
Is now available as a print book: Amazon
Contents
- Get Ready For The Python Difference
- Variables, Objects and Attributes
- The Function Object
- Scope, Lifetime and Closure
Extract 1: Local and Global ***NEW!
- Advanced Functions
- Decorators
- Class, Methods and Constructors
Extract 1: Objects Become Classes
- Inside Class
- Meeting Metaclasses
- Advanced Attributes
- Custom Attribute Access
- Single Inheritance
- Multiple Inheritance
- Class and Type
- Type Annotation
- Operator Overloading
- Python In Visual Studio Code
Extracts from the first edition
<ASIN:1871962749>
<ASIN:1871962595>
<ASIN:1871962765>
Private Attributes and Name Mangling
final version in book
Private Attributes and Object Factories
final version in book
Properties
If you program in other object oriented language you will be wondering where getters and setters come into Python.
A getter and setter is the common name for mutator functions. A getter is a function that is automatically called to complete an assignment:
temp=a.myProperty
would automatically call geta which would return the value stored in temp.
Similarly:
a,myProperty=temp
would automatically call seta(temp) to store the value of temp in a.
If you haven’t encountered this idea before you might be wondering what the advantage is over direct access to the attribute?
The answer is that the functions can process the data and check that it is valid during the transaction. Most commonly, set checks that a value is valid, and get processes the data into an acceptable form.
Python supports getters and setters using an even more general facility called a descriptor object – more of this in Chapter 10. For the moment we will concentrate on how to implement getters and setters or a Python property rather than how it all works. The descriptor mechanism that is behind the built-in property function is very clever and well worth understanding.
The property built-in function is very simple:
class property(fget=None, fset=None, fdel=None, doc=None)
It takes three functions, fget the getter, fset the setter, and fdel a function that will remove the property. You can also include a docstring as the final parameter. The function returns a property attribute which can be added to a class and which implements the getter and setter protocol.
If you don’t include a function for fset you have a read-only property.
The standard way of creating a property is neat but not particularly instructive. To show how it works let’s do things differently.
All we need are three functions:
def getx(self):
print("get")
return self._x
def setx(self, value):
print("set")
self._x = value
def delx(self):
print("delete")
del self._x
Notice that each function uses self to determine the instance that it will be used with, and it assumes that the instance has an attribute _x to use to store the value. The variable that is used to actually store the value is often called a “backing variable”. Backing variables don’t just have to be variables, they can be arbitrarily complicated data structures - you can even use a database or a remote storage service over the net. This is one of the things that makes a property so useful.
|