This was discussed a bit over on python-ideas recently, so a note from me, and one from that thread:
Or for that matter, not the reason to provide
object's internal storage via object's attribute: obj.__dict__.
Well, it IS an implementation detail that it's a dictionary, but having a dunder that gives you the object's namespace seems like a specification to me -- would you be happier to call it obj.__names__ ?
And as for having vars() be the way to get that instead -- it's pretty much universal in Python that dunders provide the implementation, while functions (such as len()) provide a universal and clean interface to the functionality -- so vars() seems quite consistent in that sense.
However, as pointed out on python-ideas, some objects have a .__dict__ and/or .__slots__ -- and THAT distinction seems to be an implementation issue leaking out.
Maybe it would be too backward incompatible, but it makes sense to me that vars() should return the union of .__dict__ and .__slots__
(though I notice that if you create __slots__ in pure Python, its names show up in dict anyway -- so clearly I'm confused...)
But the question was about (thru-the-time) relationship of vars()
vs .__dict__ ...
I believe Guido's recollection is that vars() was intended to provide easy access, particularly in a REPL.
And that accessing .__dict__ directly in code is perfectly reasonable, since you only need to do that when you are metaprogramming anyway -- which inherently requires some knowledge of internal structure of objects anyway.
I'd be interested to hear if any other folks that have been around a long time have other thoughts.