1

Please correct me if I'm wrong or let me know if i'm missing any further differences:

__get__: run code if arg is an attribute of instance

__getattr__: run code if arg is not an attribute of instance

__getattribute__: run code whether arg is an attribute of instance or not

  • 1
    `__get__` is part of the [descriptor protocol](https://docs.python.org/3/howto/descriptor.html) – juanpa.arrivillaga Jul 07 '18 at 21:24
  • It doesn't really explain the difference between \__get__ and \__getattribute__. More on \__getattr__ vs \__getattribute__ –  Jul 07 '18 at 21:25
  • 1
    It's hard to explain the difference between `__get__` and `__getattribute__` because they're only vaguely related. It's kind of like asking for the difference between `__next__` and `__getitem__`. The only answer is to explain the descriptor protocol and then explain dynamic lookup, which is either going to duplicate two large and complicated HOWTOs in the docs, which seems way too big for an SO answer (and pointless, because I doubt any of us can explain it better than Guido and Raymond), or just link to them, which would be a useless link-only answer. – abarnert Jul 07 '18 at 21:29
  • 2
    It's true that there isn't much explanation in the answer itself, but it *does* contain 5 useful links about the topic of descriptors, and reading those should make the difference clear. – Aran-Fey Jul 07 '18 at 21:29
  • A more general "how does `x.attr` work, from top to bottom, including all the places it can be hooked" question might be more useful—but that just makes it more obvious that the question is probably too broad, and really demands a blog post or something, not an SO answer – abarnert Jul 07 '18 at 21:34
  • Actually, just ran through this chart: https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/object-attribute-lookup.png. Explains it perfectly. –  Jul 07 '18 at 22:18
  • @user627154 It doesn't cover everything, though. For one, thing, it's missing the entire MRO search. Also, `__getattr__` isn't actually part of `__getattribute__`, but is called if it fails. And `type.__getattribute__`, unlike `object.__getattribute__`, calls the descriptor `__get__` if found even on the instance (with `None` as the instance argument). And if `__get__` raises an `AttributeError`… and so on. – abarnert Jul 08 '18 at 00:28

0 Answers0