weak references and threads
Philip Swartzleonard
starx at pacbell.net
Wed Apr 24 05:19:21 EDT 2002
pekka niiranen || Tue 23 Apr 2002 11:41:55p:
> Could somebody explain me in SIMPLE english what are:
>
> 1) weak references
A name that does not force the object it points to to exist.
Normally, our objects stay around for as long as we have a name for them.
If we write:
a = [1]
That particular list (i used a list because defining a list guarentees a
unique ojbect) will stay around for as long as the name 'a' exists. If
this is in a function, the name will be removed at the end of the
function, if it is in the first level of the file, it will stay around
untill told to do otherwise. That is, we say:
del a
And the name 'a' is removed. If this variable has no other names at this
point, it will be removed as well. If on the other hand, we do this:
a = [2]
b = a
We now have two names for the same object (python never copies unless
asked. Any apparent copying done by an assignemnt is due to the observable
properties of immutable types (strings, numbers, tuples), and expectations
of behavior similar to other programming languages. This is the pointer-
ish stumbling block for python, it seems). If we then:
del a
The name 'a' is removed, but because the name 'b' still points at that
object, the object is unaffected.
Now, let's take a hypothetical function weak(var), which returns a weak
reference to whatever you pas to it as var. If we write:
a = [3]
w = weak(a)
We again have two names for one variable. But now if we:
del a
The system wil reclaim the [3] list object as if w did not exist. This is
because weak references complety ignore and bypass the magic-behind-the-
scenes system called 'reference counting' that lets Python keep track of
when objects acutally need to be removed. This means you genereally have
to check and see if the object still exists each time you use it, or set
up some object to be notified when it gets destroied, and do your own
bookkeeping.
There is only one reason I know that you would want to use weak
references, and that is in the creation of advanced, customized data
structures. The point is to avoid something called 'circular references',
which is probably best explained by an example. Let's take a realy basic
class (this is right from my 2.2 IDLE prompt):
>>> class pointer:
def __del__(self):
print 'Object being removed now!'
All this does is print a message when the object is deleted. A simple
control case shows how this works:
>>> a = pointer()
>>> del a
Object being removed now!
But if we create two of these objects:
>>> a = pointer()
>>> b = pointer()
And add a regular name to each that points to the other:
>>> a.target = b
>>> b.target = a
We can then remove both objects, and:
>>> del a
>>> del b
>>>
Nothing. The system does not delete either one. It's like they've fallen
into another dimension: they are still there, they still take up space in
memory, but because we have no name for them we cannot ever reach them
from the outside world. (It would be interesting to see if we could create
a thread running on a set of objects and then remove all of those objects
from the initating part of the program, but that's beyond what i'm trying
to explain here). In reality, cyclic problems would be much more subtle,
and tend to slowly leak memory until (if the program runs long enough),
the whole thing fails. (At which point it would probably all be freed as
the interperter exits: it cannot delete it earlier because it is not
gaurenteed to be safe for the program, but it still watches over things
enough to prevent permanent system memory pollution).
The best analogy for the problem that I can think of is this. In every
released version of the old Infocom text adventure Zork (one), there was a
problem like this, but this is what comes to mind. It goes something like
this:
>look
You are in some room. There is an inflated life raft and a heavy golden
coffin here.
>put coffin in raft
[Done].
>look
You are in some room. There is an inflated life raft here. The raft seems
to contain a heavy golden coffin.
>put raft in coffin
[Done].
>look
You are in some room.
Each object can only exist in one other object's contents list, so each
put operation is essentially a move instead of a copy and delete (so much
the difference =). The principle is the same, however.
> 2) threads
Er... it's late. I better get going =).
(Shortest answer: they are a way of making the computer run your program
in two places at once, at the same time. They are often used to do long
(longer than 1/2 a second) processes in GUI based apps, so the core of the
program can continue to respond to user interaction while the work gets
done.)
> and why or when are they needed.
>
> Threads I have not used but the use of weak references
> I have seen recommended with wxpython's grid component.
If you have used pointers in C or such, weak refs share many of the
hassles (minus worrying about segfaults). But both of these things are at
least moderatly advanced, so it's ok not to have used them yet. Threading
especially can be tricky if you don't have everything else down pat-- it
has enough trickyness to it when you do.
--
Philip Sw "Starweaver" [rasx] :: www.rubydragon.com
More information about the Python-list
mailing list