Transcript
Let's talk about how to make an automatically updating attribute in Python.
Attributes don't change automatically
We have a Rectangle
class:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
self.area = self.width * self.height
When we call this class, we'll get a Rectangle
object:
>>> rect = Rectangle(3, 4)
This Rectangle
object has a width
, a height
, and an area
:
>>> rect.width
3
>>> rect.height
4
>>> rect.area
12
If we're considering acceptable to change the width
or height
or an existing Rectangle
object, we might have problem. If we change the width
of a Rectangle
the area
won't change automatically:
>>> rect.width = 10
>>> rect.area
12
This happens because we only assigned the area
one time: in our initializer method. When we first make a Rectangle
object, we set the area
in our __init__
method, and that's it.
We don't use getter methods
In a lot of programming languages, it's common to fix this problem by making a getter method. Instead of an area
attribute we would make a method (maybe called get_area
or just area
):
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
When we access the area
method now, we'll see that it's a bound method:
>>> rect = Rectangle(3, 4)
>>> rect.area
<bound method Rectangle.area of <__main__.Rectangle object at 0x7f028eb3caf0>>
We can't just access rect.area
to get our area anymore. We have to call the area
method in order to get a result:
>>> rect.area()
12
Now if we update the width
of our Rectangle
object:
>>> rect.width = 10
And call the area
method:
>>> rect.area()
40
Python will recompute the area and give us back the correct result.
In Python, writing getter methods is not common. Instead of using getter method, we tend to make a property.
We prefer properties over getter methods
We're using the property
decorator here:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
That's called a decorator because of that @
syntax.
When we use the property decorator, it will make what was previously a method into a property.
Now if we make a Rectangle
object, just like before, and we access the area
attribute:
>>> rect = Rectangle(3, 4)
>>> rect.area
12
Unlike before, we don't need to put parentheses after area
! In fact, we can't put parentheses. Simply by accessing the area
attribute we get our answer.
So if we change the width
or the height
and we access area
again, it will recompute the area automatically:
>>> rect.width = 10
>>> rect.area
40
So Python isn't actually storing the area
attribute anywhere. Instead, every time the area
attribute is accessed, it calls area
method and gives us back whatever the return value is. And it does this automatically, simply because we accessed the rect.area
attribute.
Summary
If you want to make an attribute on an object in Python that updates automatically you can use a property.
from Planet Python
via read more
No comments:
Post a Comment