On Mon, Oct 2, 2017 at 5:34 PM, Marko Rauhamaa <ma...@pacujo.net> wrote: > Chris Angelico <ros...@gmail.com>: > >> Yes, that's correct. The *descriptor* protocol is what allows >> "foo.bar" to cause a function to be executed > > That mechanism allows you to expose data fields in the API. If the > implementation later changes, you can emulate the data fields. > > I must say, though, I have yet to run into a need for descriptors.
The beauty of Python (over, say, C++) is that you can transparently convert something from being a simple data attribute to being a descriptor. The mere fact that they *exist* benefits your code; they're like a safety net that lets you do what makes sense without worrying that someday, maybe, one of these things might have to become a function. In C++, if something might ever need to be a function, it has to be a function *now*, so Best Practice is to write getters and setters for everything, just in case. In Python, you can convert it to use @property if you ever actually need to, which means you do nothing now. >> the *decorator* protocol is what lets you "tag" a function: > > i have yet to need that, either. I have *seen* a semi-useful decorator > in code once (@contextlib.contextmanager) but still would prefer > explicit dunder methods. There are plenty of programs that don't need decorators, but in some contexts, they are just beautiful. Building a web app in Flask or Django involves functions that get decorated to say what endpoints they handle, for instance. I've periodically used a simple decorator plus some info in the function's docstring to do more magic. I'm not sure where dunder methods come into this, though, as they're completely unrelated. ChrisA -- https://mail.python.org/mailman/listinfo/python-list