Calculate attribute if it doesn't exist

后端 未结 2 1974
忘掉有多难
忘掉有多难 2020-12-16 04:18

I am trying to access an attribute that shouldn\'t be created in the __init__ method of my class but can be calculated by calling another method. I am trying to

相关标签:
2条回答
  • 2020-12-16 04:42

    Pyramid (a Web framework) comes with a reify decorator that is similar to property (shown by Austin Hastings) but it works a little differently: the function is only executed once, and after that, the value returned by the function is always used. It essentially does what Austin's code does, but without having to use a separate attribute: it's a generalization of that pattern.

    You probably don't want to use a whole Web framework just for this one decorator, so here is an equivalent one I wrote:

    import functools
    
    class Descriptor(object):
        def __init__(self, func):
            self.func = func
        def __get__(self, inst, type=None):
            val = self.func(inst)
            setattr(inst, self.func.__name__, val)
            return val
    
    def reify(func):
        return functools.wraps(func)(Descriptor(func))
    

    Usage:

    class ReifyDemo:
        @reify
        def total(self):
            """Compute or return the total attribute."""
            print("calculated total")
            return 2 + 2    # some complicated calculation here
    
    r = ReifyDemo()
    print(r.total)     # prints 'calculated total 4' because the function was called
    print(r.total)     # prints just '4` because the function did not need to be called
    
    0 讨论(0)
  • 2020-12-16 04:43

    You want to use the @property decorator. Create a method, that will be accessed like a normal attribute, that does lazy computation:

    class SampleObject:
    
        def __init__(self):
            # ...
            self._total = None
    
        @property
        def total(self):
            """Compute or return the _total attribute."""
            if self._total is None:
                self.compute_total()
    
            return self._total
    
    0 讨论(0)
提交回复
热议问题