tags:

views:

52

answers:

2

I would like to do this:

def foo():
    if <a magical condition>:
        return x
    else:
        poof()

# or...
def foo():
    x = <a magical object>
    return x

def poof():
    print 'poof!'

bar = foo()  # bar points to <a magical object> but poof() is not called

foo() # prints 'poof!'

I guess it comes down to what the circumstanses are when the returned object's __del__ method is called. But maybe there is a better way. Like if the function itself knew it's returned value was being assigned. I guess I'm worried about relying on the timing of the garbage collection. Also I don't like that global at_end_of_program flag.

My solution:

class Magic:
    def __del__(s):
        poof()

def foo():
    x = Magic()
    return x

def poof():
    if not at_end_of_program:
        print 'poof!'

bar = foo()  # No poof.

foo() # prints 'poof!'
+1  A: 

A function can't tell what its return value is used for. Your solution will print poof if you re-assign to bar for example.

What's the real problem you are trying to solve?

Ned Batchelder
Yes, I would have to avoid re-assigning `bar` until after setting the `at_end_of_program` flag to True. I am trying to sometimes pass, sometimes close a COM object that gets created by a function, depending on whether it is "requested" or not by the call of the function. The COM object does not get closed when garbage collected.
bpowah
+3  A: 

I'm pretty confused by your question, but I think what you are trying to do is run a function when a value is reassigned.

Instead of doing tricky things with a __del__() method function, I suggest you just put your value into a class instance, and then overload __setattr__(). You could also overload __delattr__() to make sure you catch del(object.x) for your value x.

The very purpose of __setattr__() is to give you a hook to catch when something assigns to a member of your class. And you won't need any strange end_of_program flag. At the end of your program, just get rid of your overloaded function for __delattr__() so it doesn't get called for end-of-program cleanup.

steveha