Magic function

dg.google.groups at thesamovar.net dg.google.groups at thesamovar.net
Mon Jan 14 13:47:42 EST 2008


Hi Rüdiger,

Thanks for your message. I liked your approach and I've been trying
something along exactly these sorts of lines, but I have a few
problems and queries.

The first problem is that the id of the frame object can be re-used,
so for example this code (where I haven't defined InstanceTracker and
getInstances, but they are very closely based on the ideas in your
message):

class A(InstanceTracker):
    gval = 0
    def __init__(self):
        self.value = A.gval # each time you make a new object, give
        A.gval += 1         # it a value one larger
    def __repr__(self):
        return str(self.value)

def f2():
    a = A() # objects 0 and 2
    return getInstances(A)

def f3():
    a = A() # object 1
    return f2()

inst2 = f2()
inst3 = f3()
print inst2
print inst3

The output is:

[0]
[0, 2]

The A-variable with value 0 is not being garbage collected because
it's saved in the variable inst2, but it's also being returned by the
second call to getInstances because the frame of f2 is the same each
time (which makes sense, but may be implementation specific?). The
same problem doesn't exist when you use the stack searching method
because from f2's point of view, the only bound instance of A is the
one in that particular call of f2. If you had at the end instead of
the inst2, inst3 stuff:

print f2()
print f3()

The output is:

[0]
[2]

Again, I guess this because A with value 0 is being garbage collected
between print f2() and print f3(), but again I think this is
implementation specific? You don't have a guarantee that this object
will be garbage collected straight away do you?

So my concern here is that this approach is actually less safe than
the stack based approach because it depends on implementation specific
details in a non-straightforward way. That said, I very much like the
fact that this approach works if I write:

a = [A()]
a = [[A()]]
etc.

To achieve the same thing with the stack based approach you have to
search through all containers to (perhaps arbitrary) depth.

I also have another problem which is that I have a function decorator
which returns a callable object (a class instance not a function).
Unfortunately, the frame in which the callable object is created is
the frame of the decorator, not the place where the definition is.
I've written something to get round this, but it seems like a bit of a
hack.

Can anyone suggest an approach that combines the best of both worlds,
the instance tracking approach and the stack searching approach? Or do
I need to just make a tradeoff here?

Thanks again for all your help everyone,
Dan Goodman



More information about the Python-list mailing list