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, 王珺
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
: 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, 王珺
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@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)