[Python-ideas] The AttributeError/__getattr__ mechanism

王珺 wjun77 at gmail.com
Fri Nov 27 15:18:39 EST 2015


I think the real world use case, as *property* is so common, is just when
__getattr__ needed. So anyone using __getattr__ in practice? In fact I'm
new tweaking these advanced features of python. Any suggestions are welcome
and appreciated.


In my case, I delegate failed attribute lookups to one member of the
instance, as the given simple example in issue25634. For example, there's a
class Point,

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y

and class Circle

class Circle():
    def __init__(self, center, radius):
        self.center = center
        self.radius = radius

I don't think Circle should inherit Point. But I want to write Circle().x
instead of Circle().center.x, so I write something like
    def __getattr__(self, name):
        try:
            return getattr(self.center, name)
        except AttributeError:
            raise AttributeError("'{}' object has no attribute
'{}'".format(self.__class__.__name__, name)) from None


Another case is when I try to implement the design pattern of state. That
is, when calling window.rightClick(), the behavior differs according to the
state of the window, or window.__state. So

class ActiveState(State):
    @staticmethod
    def rightClick(self):
        print('right clicked')
class InactiveState(State):
    @staticmethod
    def rightClick(self):
        pass

and

class Window():
    def __init__(self):
        self.__state = ActiveState
    def __getattr__(self, name):
        try:
            return partial(getattr(self.__state, name), self)
        except AttributeError:
            raise AttributeError("'{}' object has no attribute
'{}'".format(self.__class__.__name__, name)) from None

(The real situation is more complicated. In fact I've written a state
module, and I think I can publish it in a week if anyone is interested.)


> Is that really an imperfection? It says right there in the docs for
__getattribute__ that you can delegate to __getattr__ by raising
AttributeError
Just like raising *StopIteration* in generator, as described in PEP479.
Although I'm not sure *StopIteration* has ever been documented as one way
to exit generator. And I admit that an unintentional AttributeError in
__getattribute__ is a rare case if ever.

2015-11-28 2:34 GMT+08:00 Andrew Barnert <abarnert at yahoo.com>:

> It seems like you can get some of the benefits of this proposal without
> backward compat issues.
>
> Instead of changing things so AttributeError from __getattribute__ or a
> descriptor no longer calls __getattr__, just add a new subclass that
> doesn't, and change the Descriptor HOWTO to suggest using that subclass
> (with a bit of discussion that says you can use AttributeError if you want
> to trigger __getattr__, but usually you won't).
>
> That wouldn't fix any current code, but it also wouldn't break any code
> that intentionally uses the features as documented. And it would make it
> easy to write correct new code.
>
> One more thing:
>
> Without descriptor, unexpected AttributeError could only come from overriding __getattribute__, which is a rare case, although still an imperfection.
>
> Is that really an imperfection? It says right there in the docs for
> __getattribute__ that you can delegate to __getattr__ by raising
> AttributeError, so if someone does that, presumably it's intentional. It's
> not like the case with descriptors, where you have to think through the
> interaction of multiple features to figure out that raising an
> AttributeError will call __getattr__, and therefore many such uses are
> probably bugs.
>
> Sent from my iPhone
>
> On Nov 27, 2015, at 09:49, 王珺 <wjun77 at gmail.com> wrote:
>
> Hello everyone:
>
> I'm suggesting a modification to the AttributeError/__getattr__ mechanism,
> see issue25634:
> http://bugs.python.org/issue25634
>
> I used __getattr__ sometimes, and descriptor especially property is so
> widely used. I wonder whether someone had encountered the same problem with
> me.
>
> However, this is a complicated problem including performance issues, and
> backward compatibility.
>
> Thanks for your attention,
> Jun Wang
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151128/dbd40bc3/attachment.html>


More information about the Python-ideas mailing list