1

I have just been reading momoko docs, and came across the following class:

class BaseHandler(RequestHandler):
    @property
    def db(self):
        return self.application.db

Every time we want to access db attribute of base_handler instance of BaseHandler, the db(self) will be called, returning self.application.db.

What is the advantage of this code over the following?

class BaseHandler(RequestHandler):
    def __init__(self):
        self.db = self.application.db

This will bind instance variable db to self.application.db.

I understand that the former approach will avoid us of having self.db in each instance. On the other hand, self.application.db has extra attribute resolution step (extra .).

Are there any advantages of the former approach that I don't see?

1 Answer 1

4

It makes db read-only. You cannot set base_handler.db, there is no setter associated with the property:

>>> class Foo(object):
...     @property
...     def bar(self): return 'spam'
... 
>>> foo = Foo()
>>> foo.bar
'spam'
>>> foo.bar = 'ham'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

You'd need to add a setter for it to be writable:

class Foo(object):
    _bar = 'spam'

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, value):
        self._bar = value

Note the @name_of_property.setter decorator; the property object itself gives you a decorator function to create a new decorator with the setter replaced with the new decorated function. There is a .deleter equivalent as well. See the property function documentation for more detail.

Sign up to request clarification or add additional context in comments.

4 Comments

Can you show an example of how the property can be made read as well as write? Yes, it is not related to the question. Thanks.
Martijn, I have just been contemplation on this, and thought up another reason. self.application.db may be accessed through descriptor and may dynamically return different db objects. As we don't really know the internals of application or how it may change in the future, we cannot get self.application.db on initialization step and hold it. And should access it through descriptor. Is this logic reasonable?
That is reasonable, yes. Storting self.db would store a static copy, while self.application.db might change.
So, when we use 3d party library, we should account for the fact that attributes may start being accessed through descriptors, and access attributes through descriptors in our code. It's a valuable conclusion. I have never thought of this before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.