So, I'm trying to figure out the best [most elegant with the least amount of code] way to allow overriding specific functions of a property [e.g., just the getter, just the setter, etc.] in python. I'm a fan of the following way of doing properties, due to the fact that all of their methods are encapsulated in the same indented block of code [it's easier to see where the functions dealing with one property stop and the functions dealing with the next begin]:
@apply
def foo[]:
"""A foobar"""
def fget[self]:
return self._foo
def fset[self, val]:
self._foo = val
return property[**locals[]]
However, if I
want to inherit from a class that defines properties in this manner, and then, say, override the foo
setter function, it seems tricky. I've done some searching and most of the answers I've found have been to define separate functions in the base class [e.g. getFoo
and setFoo
], explicitly create a property definition from them [e.g. foo = property[lambda x: x.getFoo[], lambda x, y: x.setFoo[y], lambda x: x.delFoo[]]
], and then override getFoo
, setFoo
, and delFoo
as needed.
I dislike this solution because it means I have to define lambas for every
single property, and then write out each function call [when before I could have just done property[**locals[]]
]. I also don't get the encapsulation that I had originally.
Ideally, what I would like to be able to do would be something like this:
class A[object]:
def __init__[self]:
self.foo = 8
@apply
def foo[]:
"""A foobar"""
def fget[self]:
return self._foo
def fset[self, val]:
self._foo = val
return property[**locals[]]
class ATimesTwo[A]:
@some_decorator
def foo[]:
def fset[self, val]:
self._foo = val * 2
return something
And then the output would look something like:
>>> a = A[]
>>> a.foo
8
>>> b = ATimesTwo[]
>>> b.foo
16
Basically, ATimesTwo
inherits the getter function from A
but overrides the setter function. Does anybody know of a way to do this [in a manner that looks similar to the example
above]? What function would the some_decorator
look like, and what should the foo
function return?
Join us and get access to thousands of tutorials and a community of expert Pythonistas.
Unlock This Lesson
This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.
Unlock This Lesson
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.
- Transcript
- Comments & Discussion
00:00 Overriding Properties in Subclasses. When you create Python classes that include properties and release them in a package or library, you should expect that your users do a wide variety of things with them.
00:14 One of these things could be subclassing them to customize their functionalities. In these cases, your users have to be careful and be aware of a subtle gotcha.
00:25 If you partially override a property, then you
lose the non-overridden functionality. For example, suppose you are coding an Employee
class to manage employee information in your
company’s internal accounting system. You already have a class called Person
, and you think about subclassing it to reuse its functionality.
01:01 Person
has a .name
attribute implemented as a property. The
current implementation of .name
doesn’t meet the requirement of returning the name in uppercase letters.
01:14
Here’s how you end up solving this. In Employee
, you override .name
to make sure that when you access the attribute,
you get the employee name in uppercase.
02:03
Employee
works as you need. It returns the name using uppercase letters. However, subsequent tests uncover an unexpected behavior.
You may be wondering what’s happened. When you override an existing property from a parent class, you override the whole functionality of that property.
02:25 In this example, you reimplemented the
getter method only. Because of that, .name
lost the rest of the functionality from the base class. You don’t have a setter method any longer.
02:39 The idea is that if you ever need to override a property in a subclass, then you should provide all of the functionality you need in the new version of the property at hand.
02:56 With this code in place, you can now set the employee’s name without issue.
03:29 Now that you’ve completed the content of the course, in the next section, you’ll review what you’ve learned.