Story behind vars() vs .__dict__

Hello, I would easily bet 10 bucks that vars() is the least known, and least used, of the Python builtin functions. My mental model of it was: it was introduced (perhaps in Python3) to "harmonize" all the existing .__dict__ stuff, and provide more abstract interface for it, with .__dict__ patiently waiting its deprecation in CPython 10 or something. Was I wrong with thinking like that, and finding that vars() was already in the docs of CPython 1.4, the earliest doc version hosted at python.org: https://docs.python.org/release/1.4/lib/node26.html#SECTION00330000000000000... So it seems it was around "always", but then the question is why both vars() and .__dict__ are round for so long, and there was no (successful) attempt to stop breaking object encapsulation e.g. on transitioning to Python3000? Anybody has any references to the story of them? I can't find anything relevant so far. I in particular made sure to google for "vars site:python-history.blogspot.com" with 0 hits. Expected clarification on ".__dict__ breaking object encapsulation": Usually, object attributes are used to access "some small piece of data" "stored inside" an object. .__dict__ is not like that. Depending on how you look at it, its either-or: 1. A *metadata* about an object (object's representation as a dict), and then it makes sense to use a dedicated access means for that metadata, exactly what vars() provides. 2. Leak of an implementation detail, because a particular Python implementation uses a dict as internal storage for modules, classes, instances, and then .__dict__ just gives blatant access to this internal storage, bypassing normal object semantics. -- Best regards, Paul mailto:pmiscml@gmail.com

On 22/12/20 12:36 am, Paul Sokolovsky wrote:
Expected clarification on ".__dict__ breaking object encapsulation":
Encapsulation is not something that Python has ever been big on. There are plenty of places where implementation details are exposed, and we don't regard that as a problem. -- Greg

Hello, On Tue, 22 Dec 2020 01:10:17 +1300 Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
On 22/12/20 12:36 am, Paul Sokolovsky wrote:
Expected clarification on ".__dict__ breaking object encapsulation":
Encapsulation is not something that Python has ever been big on. There are plenty of places where implementation details are exposed, and we don't regard that as a problem.
That's still not the reason to e.g. make the value of the proverbial LOAD_METHOD opcode be available via dict type attribute, like: dict.LOAD_METHOD. Or for that matter, not the reason to provide object's internal storage via object's attribute: obj.__dict__. But the question was about (thru-the-time) relationship of vars() vs .__dict__ ... -- Best regards, Paul mailto:pmiscml@gmail.com

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. -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
participants (3)
-
Chris Barker
-
Greg Ewing
-
Paul Sokolovsky