Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #89795 > unrolled thread

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

Started byvasudevram <vasudevram@gmail.com>
First post2015-05-02 13:02 -0700
Last post2015-05-03 03:52 -0700
Articles 17 — 8 participants

Back to article view | Back to comp.lang.python


Contents

  Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-02 13:02 -0700
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? Tim Chase <python.list@tim.thechases.com> - 2015-05-02 15:17 -0500
      Re: Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-02 14:07 -0700
      Re: Inner workings of this Python feature: Can a Python data structure reference itself? Cecil Westerhof <Cecil@decebal.nl> - 2015-05-02 23:06 +0200
        Re: Inner workings of this Python feature: Can a Python data structure reference itself? MRAB <python@mrabarnett.plus.com> - 2015-05-03 00:07 +0100
        Re: Inner workings of this Python feature: Can a Python data structure reference itself? Tim Chase <python.list@tim.thechases.com> - 2015-05-02 20:57 -0500
        Re: Inner workings of this Python feature: Can a Python data structure reference itself? Ian Kelly <ian.g.kelly@gmail.com> - 2015-05-02 22:29 -0600
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? Tim Chase <python.list@tim.thechases.com> - 2015-05-02 15:10 -0500
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? Terry Reedy <tjreedy@udel.edu> - 2015-05-02 19:17 -0400
      Re: Inner workings of this Python feature: Can a Python data structure reference itself? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-05-03 21:10 +1000
      Re: Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-03 05:59 -0700
        Re: Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-03 06:05 -0700
        Re: Inner workings of this Python feature: Can a Python data structure reference itself? Chris Angelico <rosuav@gmail.com> - 2015-05-03 23:08 +1000
          Re: Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-03 08:46 -0700
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? Ian Kelly <ian.g.kelly@gmail.com> - 2015-05-02 22:43 -0600
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? Chris Angelico <rosuav@gmail.com> - 2015-05-03 15:46 +1000
    Re: Inner workings of this Python feature: Can a Python data structure reference itself? vasudevram <vasudevram@gmail.com> - 2015-05-03 03:52 -0700

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

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-02 13:02 -0700
SubjectInner workings of this Python feature: Can a Python data structure reference itself?
Message-ID<387ac520-9da3-411a-a3b8-b326e1e8a2c0@googlegroups.com>
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.

Thanks
Vasudev Ram
Site: www.dancingbison.com
Python posts: jugad2.blogspot.com/search/label/python

[toc] | [next] | [standalone]


#89796

FromTim Chase <python.list@tim.thechases.com>
Date2015-05-02 15:17 -0500
Message-ID<mailman.26.1430597813.12865.python-list@python.org>
In reply to#89795
[dangit, had Control down when I hit <enter> and it sent prematurely]

On 2015-05-02 13:02, vasudevram wrote:
> http://jugad2.blogspot.in/2015/05/can-python-data-structure-reference.html
>
> https://docs.python.org/2/reference/datamodel.html
>
> and saw this excerpt:
> 
> [ CPython implementation detail: CPython currently uses a
> reference-counting scheme with (optional) delayed
> detection of cyclically linked garbage, which collects
> most objects as soon as they become unreachable, but is
> not guaranteed to collect garbage containing circular
> references. ]
> 
> Not sure whether it is relevant to the topic at hand,
> since, on the one hand, it uses the words "cyclically
> linked", but on the other, it says "garbage collection".

The gotcha happens in a case where you do something like this:

  lst = []
  lst.append(lst)  # create a cycle
  del lst

This creates a cycle, then makes it unreachable, but the list is
still referenced by itself, so the reference count never drops to
zero (where it would get GC'd), and thus that item lingers around in
memory.

If you know that you're creating such cyclical structures, it's best
to manually unlink them before freeing them:

  lst = []
  lst.append(lst) # create the cycle
  lst[:] = []   # break the cycle
  # or lst.remove(lst) # though this takes more care
  del lst

-tkc



[toc] | [prev] | [next] | [standalone]


#89798

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-02 14:07 -0700
Message-ID<d2a9b8d5-beac-4470-81bf-4654d7f68630@googlegroups.com>
In reply to#89796
On Sunday, May 3, 2015 at 1:47:04 AM UTC+5:30, Tim Chase wrote:
> [dangit, had Control down when I hit <enter> and it sent prematurely]
> 
> On 2015-05-02 13:02, vasudevram wrote:
> > http://jugad2.blogspot.in/2015/05/can-python-data-structure-reference.html
> >
> > https://docs.python.org/2/reference/datamodel.html
> >
> > and saw this excerpt:
> > 
> > [ CPython implementation detail: CPython currently uses a
> > reference-counting scheme with (optional) delayed
> > detection of cyclically linked garbage, which collects
> > most objects as soon as they become unreachable, but is
> > not guaranteed to collect garbage containing circular
> > references. ]
> > 
> > Not sure whether it is relevant to the topic at hand,
> > since, on the one hand, it uses the words "cyclically
> > linked", but on the other, it says "garbage collection".
> 
> The gotcha happens in a case where you do something like this:
> 
>   lst = []
>   lst.append(lst)  # create a cycle
>   del lst
> 
> This creates a cycle, then makes it unreachable, but the list is
> still referenced by itself, so the reference count never drops to
> zero (where it would get GC'd), and thus that item lingers around in
> memory.
> 
> If you know that you're creating such cyclical structures, it's best
> to manually unlink them before freeing them:
> 
>   lst = []
>   lst.append(lst) # create the cycle
>   lst[:] = []   # break the cycle
>   # or lst.remove(lst) # though this takes more care
>   del lst
> 
> -tkc

Thanks for the reply. Will check that out.

[toc] | [prev] | [next] | [standalone]


#89806

FromCecil Westerhof <Cecil@decebal.nl>
Date2015-05-02 23:06 +0200
Message-ID<87a8xmn0yp.fsf@Equus.decebal.nl>
In reply to#89796
Op Saturday 2 May 2015 22:17 CEST schreef Tim Chase:

> [dangit, had Control down when I hit <enter> and it sent
> prematurely]
>
> On 2015-05-02 13:02, vasudevram wrote:
>> http://jugad2.blogspot.in/2015/05/can-python-data-structure-reference.html
>>
>> https://docs.python.org/2/reference/datamodel.html
>>
>> and saw this excerpt:
>>
>> [ CPython implementation detail: CPython currently uses a
>> reference-counting scheme with (optional) delayed
>> detection of cyclically linked garbage, which collects
>> most objects as soon as they become unreachable, but is
>> not guaranteed to collect garbage containing circular
>> references. ]
>>
>> Not sure whether it is relevant to the topic at hand,
>> since, on the one hand, it uses the words "cyclically
>> linked", but on the other, it says "garbage collection".
>
> The gotcha happens in a case where you do something like this:
>
> lst = []
> lst.append(lst)  # create a cycle
> del lst
>
> This creates a cycle, then makes it unreachable, but the list is
> still referenced by itself, so the reference count never drops to
> zero (where it would get GC'd), and thus that item lingers around in
> memory.

Maybe look at Java? If my memory is correct, the JVM gc reclaims those
kind of things also.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#89812

FromMRAB <python@mrabarnett.plus.com>
Date2015-05-03 00:07 +0100
Message-ID<mailman.33.1430608033.12865.python-list@python.org>
In reply to#89806
On 2015-05-02 22:06, Cecil Westerhof wrote:
> Op Saturday 2 May 2015 22:17 CEST schreef Tim Chase:
>
>> [dangit, had Control down when I hit <enter> and it sent
>> prematurely]
>>
>> On 2015-05-02 13:02, vasudevram wrote:
>>> http://jugad2.blogspot.in/2015/05/can-python-data-structure-reference.html
>>>
>>> https://docs.python.org/2/reference/datamodel.html
>>>
>>> and saw this excerpt:
>>>
>>> [ CPython implementation detail: CPython currently uses a
>>> reference-counting scheme with (optional) delayed
>>> detection of cyclically linked garbage, which collects
>>> most objects as soon as they become unreachable, but is
>>> not guaranteed to collect garbage containing circular
>>> references. ]
>>>
>>> Not sure whether it is relevant to the topic at hand,
>>> since, on the one hand, it uses the words "cyclically
>>> linked", but on the other, it says "garbage collection".
>>
>> The gotcha happens in a case where you do something like this:
>>
>> lst = []
>> lst.append(lst)  # create a cycle
>> del lst
>>
>> This creates a cycle, then makes it unreachable, but the list is
>> still referenced by itself, so the reference count never drops to
>> zero (where it would get GC'd), and thus that item lingers around in
>> memory.
>
> Maybe look at Java? If my memory is correct, the JVM gc reclaims those
> kind of things also.
>
Python _does_ have a secondary mechanism for cleaning up such reference
cycles using mark-and-sweep:

https://docs.python.org/3/reference/datamodel.html

[toc] | [prev] | [next] | [standalone]


#89822

FromTim Chase <python.list@tim.thechases.com>
Date2015-05-02 20:57 -0500
Message-ID<mailman.41.1430619381.12865.python-list@python.org>
In reply to#89806
On 2015-05-02 23:06, Cecil Westerhof wrote:
> Op Saturday 2 May 2015 22:17 CEST schreef Tim Chase:
>> This creates a cycle, then makes it unreachable, but the list is
>> still referenced by itself, so the reference count never drops to
>> zero (where it would get GC'd), and thus that item lingers around
>> in memory.
> 
> Maybe look at Java? If my memory is correct, the JVM gc reclaims
> those kind of things also.

The two most common ways of doing garbage collection are
reference-counting and mark-and-sweep. They're not mutually
exclusive, and can be combined, but each has advantages to counter
disadvantages of the other.  In reference-counting, you have the
overhead of incrementing/decrementing a counter and the
above-mentioned unreachability issue.  With mark-and-sweep, you can
end up with pauses as the VM rejiggers memory.

It's also my understanding that Jython uses the JVM and thus gets the
JVM's generational mark-and-sweep memory management instead of the
reference-counting that the CPython implementation does.  The GC
technique isn't part of the Python spec (AFAIK), so it's up to the
individual implementation which one to use.  MRAB's post-with-link
regarding CPython's implementation suggests that CPython does
indeed provide optional mark-and-sweep style collection:

    """
    CPython implementation detail: CPython currently uses a
    reference-counting scheme with (optional) delayed detection
    of cyclically linked garbage, which collects most objects as
    soon as they become unreachable, but is not guaranteed to
    collect garbage containing circular references. See the
    documentation of the gc module for information on controlling
    the collection of cyclic garbage. Other implementations act
    differently and CPython may change. Do not depend on
    immediate finalization of objects when they become
    unreachable (so you should always close files explicitly).
    """

So it sounds like you have to request such a mark-and-sweep from
the gc module.

-tkc


[toc] | [prev] | [next] | [standalone]


#89826

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-05-02 22:29 -0600
Message-ID<mailman.43.1430627424.12865.python-list@python.org>
In reply to#89806
On Sat, May 2, 2015 at 7:57 PM, Tim Chase <python.list@tim.thechases.com> wrote:
> So it sounds like you have to request such a mark-and-sweep from
> the gc module.

You *can* request it. But as long as it hasn't been explicitly
disabled (by calling gc.disable()), the mark-and-sweep garbage
collection will also run automatically -- just not necessarily
immediately.

[toc] | [prev] | [next] | [standalone]


#89797

FromTim Chase <python.list@tim.thechases.com>
Date2015-05-02 15:10 -0500
Message-ID<mailman.27.1430598386.12865.python-list@python.org>
In reply to#89795
On 2015-05-02 13:02, 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.
> 
> Thanks
> Vasudev Ram
> Site: www.dancingbison.com
> Python posts: jugad2.blogspot.com/search/label/python
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

[toc] | [prev] | [next] | [standalone]


#89813

FromTerry Reedy <tjreedy@udel.edu>
Date2015-05-02 19:17 -0400
Message-ID<mailman.34.1430608657.12865.python-list@python.org>
In reply to#89795
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

[toc] | [prev] | [next] | [standalone]


#89858

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-05-03 21:10 +1000
Message-ID<5546022f$0$13008$c3e8da3$5496439d@news.astraweb.com>
In reply to#89813
On Sun, 3 May 2015 09:17 am, Terry Reedy wrote:

> 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.

No, that was already fixed by 1.5:

[steve@ando ~]$ python1.5
Python 1.5.2 (#1, Aug 27 2012, 09:09:18)  [GCC 4.1.2 20080704 (Red Hat
4.1.2-52)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> L = []
>>> L.append(L)
>>> print L
[[...]]


I'm not sure when it was fixed -- possibly 1.4?



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#89865

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-03 05:59 -0700
Message-ID<69353f16-7c04-469d-b3ac-05fbe75667d2@googlegroups.com>
In reply to#89813
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

[toc] | [prev] | [next] | [standalone]


#89867

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-03 06:05 -0700
Message-ID<667d6137-a01a-42d0-ab47-4ec3930d82c7@googlegroups.com>
In reply to#89865
On Sunday, May 3, 2015 at 6:30:16 PM UTC+5:30, vasudevram wrote:
> 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

I may have needed to put the "experiments" step in there as well :)

See:

http://en.wikipedia.org/wiki/Scientific_method

[toc] | [prev] | [next] | [standalone]


#89868

FromChris Angelico <rosuav@gmail.com>
Date2015-05-03 23:08 +1000
Message-ID<mailman.66.1430658498.12865.python-list@python.org>
In reply to#89865
On Sun, May 3, 2015 at 10:59 PM, vasudevram <vasudevram@gmail.com> wrote:
> 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 just took a glance at your blog post, and it's reasonably clear now.
(Though I tend to try to avoid making substantive edits to blog posts
once they've been published and read; a codicil, or at very least an
italicized comment saying "(Edit: Actually, blah blah blah.)", is
clearer. Of course, trivial edits like typos can be corrected - nobody
would be bothered by those unexpectedly changing.) Posts to the
newsgroup/mailing list basically can't be edited, so the normal way to
acknowledge an error or correction is simply a follow-up post.

ChrisA

[toc] | [prev] | [next] | [standalone]


#89875

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-03 08:46 -0700
Message-ID<68c2b223-783d-4892-9e23-9f5163ab65da@googlegroups.com>
In reply to#89868
On Sunday, May 3, 2015 at 6:38:28 PM UTC+5:30, Chris Angelico wrote:
> On Sun, May 3, 2015 at 10:59 PM, vasudevram <vasudevram@gmail.com> wrote:
> > 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 just took a glance at your blog post, and it's reasonably clear now.
> (Though I tend to try to avoid making substantive edits to blog posts
> once they've been published and read; a codicil, or at very least an
> italicized comment saying "(Edit: Actually, blah blah blah.)", is
> clearer. Of course, trivial edits like typos can be corrected - nobody
> would be bothered by those unexpectedly changing.) Posts to the
> newsgroup/mailing list basically can't be edited, so the normal way to
> acknowledge an error or correction is simply a follow-up post.
> 
> ChrisA

Good points, thanks.

[toc] | [prev] | [next] | [standalone]


#89827

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-05-02 22:43 -0600
Message-ID<mailman.44.1430628229.12865.python-list@python.org>
In reply to#89795
On Sat, May 2, 2015 at 2:17 PM, Tim Chase <python.list@tim.thechases.com> wrote:
> If you know that you're creating such cyclical structures, it's best
> to manually unlink them before freeing them:
>
>   lst = []
>   lst.append(lst) # create the cycle
>   lst[:] = []   # break the cycle
>   # or lst.remove(lst) # though this takes more care
>   del lst

In general, this shouldn't be necessary. I believe that reference
cycles are guaranteed to be cleaned up in all major implementations of
Python, except that in CPython prior to version 3.4 reference cycles
containing objects with finalizers would not be collected. So the
better advice would be "don't use finalizers in reference cycles if
you need compatibility with Python 3.3 or earlier."

[toc] | [prev] | [next] | [standalone]


#89830

FromChris Angelico <rosuav@gmail.com>
Date2015-05-03 15:46 +1000
Message-ID<mailman.47.1430632020.12865.python-list@python.org>
In reply to#89795
On Sun, May 3, 2015 at 2:43 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Sat, May 2, 2015 at 2:17 PM, Tim Chase <python.list@tim.thechases.com> wrote:
>> If you know that you're creating such cyclical structures, it's best
>> to manually unlink them before freeing them:
>>
>>   lst = []
>>   lst.append(lst) # create the cycle
>>   lst[:] = []   # break the cycle
>>   # or lst.remove(lst) # though this takes more care
>>   del lst
>
> In general, this shouldn't be necessary. I believe that reference
> cycles are guaranteed to be cleaned up in all major implementations of
> Python, except that in CPython prior to version 3.4 reference cycles
> containing objects with finalizers would not be collected. So the
> better advice would be "don't use finalizers in reference cycles if
> you need compatibility with Python 3.3 or earlier."

It's not strictly necessary, but you can help things along by breaking
the cycle - if you're doing this kind of thing in a loop, breaking the
cycle will most likely give more consistent memory usage, whereas the
GC will potentially pick up a bunch of them all at once.

In simple applications, it's not a big deal either way. Just write
your code, and let Python worry about memory. But if it doesn't cost
you much to break the loop, you may as well do it  Sometimes it even
improves code clarity - showing that you're definitely done with this
thing now, even though in theory you might still be iterating over it.
Just don't warp your code around memory usage, because that's not what
Python's meant for. :)

ChrisA

[toc] | [prev] | [next] | [standalone]


#89851

Fromvasudevram <vasudevram@gmail.com>
Date2015-05-03 03:52 -0700
Message-ID<96759e19-8150-4fcf-83bc-b945efb2409e@googlegroups.com>
In reply to#89795
On Sunday, May 3, 2015 at 1:32:14 AM UTC+5:30, 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.
> 
> Thanks
> Vasudev Ram
> Site: www.dancingbison.com
> Python posts: jugad2.blogspot.com/search/label/python


Thanks again to all who answered. I will reply separately today to individual answers that need a reply.

- Vasudev

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web