Inner workings of this Python feature: Can a Python data structure reference itself?

vasudevram vasudevram at gmail.com
Sun May 3 08:59:54 EDT 2015


On Sunday, May 3, 2015 at 4:48:11 AM UTC+5:30, Terry Reedy wrote:
> On 5/2/2015 4:02 PM, vasudevram wrote:
> > Hi group,
> >
> > Please refer to this blog post about code showing that a Python data
> > structure can be self-referential:
> >
> > http://jugad2.blogspot.in/2015/05/can-python-data-structure-reference.html
> >
> >  Gotten a couple of comments on it already, but interested in hearing
> > thoughts of Python core dev team members or others who can comment on
> > the internals of how this feature operates, why, etc.
> 
> Please correct the following:
>    "g (a list) contains itself as a list item (of g)."
> g is a dict, as you yourself later said.
> 
> "Case 2) But if the evaluation works in a different order, i.e. the 
> globals() function is first called (before the variable g is created), 
> then at this point its return value (the dict) should not contain the 
> item with key 'g' (and value g), and it is this dict that should get 
> assigned to the variable g. Hence when we print g, we should not see g 
> again within it."
> 
> This seems like you are presenting this as a statement of fact, but you 
> then admit it is false.  The lead in sentence should more carefully 
> state that what follows are possible hypotheses.  one is true and the 
> other (mostly) not.
> 
> The key point is the meaning of "the globals() function returns a dict 
> representing the current global symbol table,"  "Global symbol table" is 
> an abstraction.  In CPython, the implementation is a dict and globals 
> returns that dict, not a copy.  Python generally does not copy objects 
> unless requested.
> 
> Similarly, locals() returns a dict representing the current local symbol 
> table. In a CPython class statement, the local symbol table is 
> implemented with a dict, and locals() is that dict.  In a CPython def 
> statement, the local symbol table is implemented as a C array (of 
> pointers to PyObjects). Locals() is a dict (created just once) updated 
> from local names in the code object and the objects in the array *at the 
> time of the call*
> 
>  >>> def f(a):
> 	g = locals()
> 	print(id(g), g)
> 	g = locals()
> 	print(id(g), g)
> 	
>  >>> f(3)
> 56288136 {'a': 3}
> 56288136 {'a': 3, 'g': {...}}
> 
> 'Case 2" applies for the first locals() call, but only for the first.
> 
> I believe that there was a time when printing a recursive structure hit 
> the recursion limit like your flatten did. But I will not reload 1.5 to 
> check.
> 
> -- 
> Terry Jan Reedy

Terry Reedy:

Thanks for the detailed answer. I have corrected the list vs. dict mistake in a comment to my original post on my blog. Don't want to edit the post itself since some readers will get it twice via feed readers.

Re. statement of fact vs. hypotheses. While I'm not sure of your exact meaning in that paragraph, I understand the concept, and yes, I was not clear enough in phrasing that part. It should have read like something along these lines:

Observations -> One or more hypotheses -> deductions -> one or more alternative conclusions.

I mixed that up a bit.

Thanks.
- Vasudev



More information about the Python-list mailing list