p1 = point(0, 0)
l1 = line(1, 3, -4, 5)
c1 = circle(-2, 3, 1)
show()
In each __init__() method of the point, line, and circle objects I add
self to a list in a separate module, then show() uses this list to
actually draw the objects. This works except:
l1 = line(point(1, 3), point(-4, 5))
c1 = circle(point(-2, 3), 1)
adds the references to the points used to define the objects to the
render list. I only want objects that have been assigned to a variable
to be rendered. (Try to ignore the function overloading.)
So how can I tell if an instance of point, line or circle has actually
been assigned to a variable?
--
bytecolor
You can't really distinguish whether an object has been assigned to a
variable, an item in a list, an attribute, etc etc -- all of these
assignments are much the same thing, there is nothing special about
variables to distinguish them from the other kind of 'labels'. Indeed,
for example, global variables are EXACTLY the same thing as attributes
of a module objects which in turn are exactly the same things as values
in the module's __dict__ -- so, any hopes of distinguishing between
variables, attributes, and items inside a container, must clearly be
abandoned.
You can do various other things that might come close to what you want,
such as using weak references in your list (if no 'true' reference
exists, an object goes away and _weak_ references to that object let you
check if the object is still around or has gone away) -- that will let
you know whether the object has been assigned to *anything* (you can
perform a similar task by checking on the number of references extant to
an object). But checking if the existing references are indeed
'variables' or something else is a hard, unrewarding task.
Alex
In each __init__() I use:
aptbase.drawables.append(weakref.ref(self))
Then in show():
for d in aptbase.drawables:
o = d()
if o is not None:
# render it
--
bytecolor
Looks good, so apparently you didn't particularly care about assignment
to variables vs assignment to other "labels" -- great!
My favourite way to use weakref is slightly different: I would have
aptbase.drawables = weakref.WeakValueDictionary
then in each __init__
aptbase.drawables[len(aptbase.drawables)] = self
then in show:
for o in aptbase.drawables.values():
# render it
Not a vastly different idiom from yours, mind you, but I like not having
to check whether an object has gone away -- a WeakValueDictionary's
entries just disappear when the value object goes away, so that at any
time looping on its .values() is safe as brick houses!-)
Alex
a,b,c = Something(), Something(), Something()
b = None
d = Something() # overwrites the d entry.
I'd use:
aptbase.drawables[id(self)] = self
--
-Scott David Daniels
scott....@acm.org
Good point -- the id isn't going to be reused until self is gone, of
course. I normally use a monotonically increasing counter (global or in
self's class), but there's no real reason for that -- id is simpler (and
using len as I had is definitely bugprone, as you mention).
Alex
In a tiny demo of what exactly the problem is, I managed to
mess up the comment.
a, b, c = Something(), Something(), Something()
b = None
d = Something() # overwrites the _c_ entry.
Silly me.
--Scott David Daniels
scott....@acm.org