[Python-ideas] The AttributeError/__getattr__ mechanism

Chris Angelico rosuav at gmail.com
Fri Nov 27 18:27:57 EST 2015


On Sat, Nov 28, 2015 at 10:23 AM, 王珺 <wjun77 at gmail.com> wrote:
> However, widget.item may be None, while e.g. there are four widgets but only
> three items in total. In this case I should fill the area with white. But in
> this version of show, I just FORGET item can be None. So the traceback
> infomation: 'Window' object has no attribute 'backgroundImg'. In fact it
> takes a while before I find the cause is the AttributeError/__getattr__
> mechanism.

Hmm. A possibly more general solution is to declare that a function
mustn't ever raise a certain exception.

from functools import wraps
def dontraise(exc):
    def wrapper(f):
        @wraps(f)
        def inner(*a,**kw):
            try:
                f(*a,**kw)
            except exc as e:
                raise RuntimeError from e
        return inner
    return wrapper

class A():
    def __init__(self, x=None):
        self.x = x

    @property
    @dontraise(AttributeError)
    def t(self):
        return self.x.t

    def __getattr__(self, name):
        return 'default'

print(A().t)


By guarding your function with dontraise(AttributeError), you declare
that any AttributeError it raises must not leak out. Same as the
property change, but not bound to the property class itself.

ChrisA


More information about the Python-ideas mailing list