Proper way of using properties with try and except

前端 未结 1 1217
星月不相逢
星月不相逢 2021-02-09 01:55

I have classes that have attributes set with @property decorator. They function as getter and setter using try and except clauses inside them. If attribute is not s

相关标签:
1条回答
  • 2021-02-09 02:16

    So long as you are using at least Python 3.2, use the functools.lru_cache() decorator.

    import functools
    class SubClass(TopClass):
    
        @property
        @functools.lru_cache()
        def thing(self):
            thing = get_some_thing_from_db('thing')
            if not thing:
                raise AttributeError()
            return TheThing(thing)
    

    A quick runnable example:

    >>> import functools
    >>> class C:
        @property
        @functools.lru_cache()
        def foo(self):
            print("Called foo")
            return 42
    
    
    >>> c = C()
    >>> c.foo
    Called foo
    42
    >>> c.foo
    42
    

    If you have a lot of these you can combine the decorators:

    >>> def lazy_property(f):
        return property(functools.lru_cache()(f))
    
    >>> class C:
        @lazy_property
        def foo(self):
            print("Called foo")
            return 42
    
    
    >>> c = C()
    >>> c.foo
    Called foo
    42
    >>> c.foo
    42
    

    If you are still on an older version of Python there's a fully featured backport of lru_cache on ActiveState although as in this case you're not passing any parameters when you call it you could probably replace it with something much simpler.

    @YAmikep asks how to access the cache_info() method of lru_cache. It's a little bit messy, but you can still access it through the property object:

    >>> C.foo.fget.cache_info()
    CacheInfo(hits=0, misses=1, maxsize=128, currsize=1)
    
    0 讨论(0)
提交回复
热议问题