Arup Rakshit wrote: > I read today 2 methods regarding the customizing the attribute > access:__getattr__ and __getattribute__ from > https://docs.python.org/3/reference/datamodel.html#special-method-names. > What I understood about them is that __getattr__ is called when the > requested attribute is not found, and an AttributeError is raised. But > later is called everytime unconditionally. I wrote a simple 2 input > calculator program, where only 2 operations are permitted Addition and > Subtraction. Anything else will cause an not permitted error. > > class OperationNotPermitted(AttributeError): > pass > > class Calc: > def __init__(self, x, y): > self.x = x > self.y = y > > def __getattr__(self, name): > if name == "sum": > return self.x + self.y > elif name == 'minus': > return self.x - self.y > else: > raise OperationNotPermitted("operation {} is not > permitted".format(name)) > > And here is a run down: > > from customize_attr_access import * > cal = Calc(12, 10) > cal.sum > 22 > cal.minus > 2 > cal.mul > Traceback (most recent call last): > Python Shell, prompt 5, line 1 > # Used internally for debug sandbox under external interpreter > File "/Users/aruprakshit/python_playground/customize_attr_access.py", > line 15, in __getattr__ > raise OperationNotPermitted("operation {} is not > permitted".format(name)) > customize_attr_access.OperationNotPermitted: operation mul is not > permitted > > If I replace __getattr__ with __getattribute__ I found the program works > exactly same.
No, it doesn't, as __getattribute__ is called for x, and y, too. def __getattribute__(self, name): if name == "sum": return self.x + self.y elif name == 'minus': return self.x - self.y else: raise OperationNotPermitted("operation {} is not permitted".format(name)) Accessing cal.sum will therefore trigger a __getattribute__("x") call which in turn will raise an OperationNotPermitted("operation x ...") exception. > Now my questions is in real world when you have to pick > between these 2 pair of special method which protocols a Python dev > checks to pick either of the one? Is there any such thing, or either one > is fine. Can anyone elaborate this to educate me please? __getattribute__() is rarely needed, __getattr__() is useful when the list of calculated attributes is open-ended and uniform (think proxy). When there is a finite number of calculated attributes the best way to implement them is usually a property: class Calc: def __init__(self, x, y): self.x = x self.y = y @property def sum(self): return self.x + self.y @property def difference(self): return self.x - self.y > > doc said: > > > This method should either return the (computed) attribute value or > raise an AttributeError exception. > > Another question: > > My question is that: Can I raise a domain error like > OperationNotPermitted when raising instead of AttributeError ? You just did ;) I don't think it's a good idea, though. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor