DEV Community

Mike Lezhnin
Mike Lezhnin

Posted on

2 3

Python `property`

Welp, I discovered descriptors in python. I was trying to implement something similar to @property, which I thought of as some weird decorator, which turns a function into some sort of a function that is called without the () brackets.
Of course an automatically called function is something impossible, but one could inject something into cls.__getattr__ perhaps? Turns out this is also impossible (afaik) - to get to the class one has to either hook into where the function is defined; or have something called to reach self and then hook into __getattr__, but we don't have anything being called...

After understanding that I got no clue how to create property on my own, I googled for that, and now I got this:

class prop:
    def __init__(self, fget):
        self.fget = fget
    def __get__(self, obj, objtype=None):
        return self.fget(obj)

class A:
    @prop
    def data(self):
        return 32
Enter fullscreen mode Exit fullscreen mode

If I produce an object with a method __get__(self, obj, objtype=None) inside another class, then this object is magically called without any brackets. Yeap, descriptors.

Btw, here is a link for more info: https://docs.python.org/3/howto/descriptor.html#properties

As for what I wanted to do, I now got this:

def lazy(load='scan'):
    class desc:
        def __init__(self, prop):
            self.attr = f'_{prop.__name__}'
        def __get__(self, obj, objtype = None):
            if not hasattr(obj, self.attr) or getattr(obj, self.attr) == None:
                getattr(obj, load)()
            return getattr(obj, self.attr)
    return desc

class A:
    def __init__(self):
        pass
    @lazy()
    def data(): pass
    @lazy()
    def other(): pass
    def scan(self):
        self._data = 42
        self._other = 34
Enter fullscreen mode Exit fullscreen mode

Now I can have multiple properties lazily loaded when they are needed. Yeaay.

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay