[Python-ideas] The AttributeError/__getattr__ mechanism

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


At first I think of adding AttributeMissError. In that case,
object.__getattr__ (here self.x.__getattr__) could turn AttributeMissError
to AttributeError.
But after some consideration I think there's no need to add an extra
Exception. Just ignore the title of that issue.

2015-11-28 4:20 GMT+08:00 Guido van Rossum <guido at python.org>:

> I'm confused about how the proposal would work. How would you prevent
> self.x.t from also raising AttributeMissError (thereby defeating its
> purpose)?
>
> On Fri, Nov 27, 2015 at 12:18 PM, 王珺 <wjun77 at gmail.com> wrote:
>
>> 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/
>>>
>>>
>>
>> _______________________________________________
>> 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/
>>
>
>
>
> --
> --Guido van Rossum (python.org/~guido)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151128/5e77bdeb/attachment.html>


More information about the Python-ideas mailing list