13

I'm trying to create a function to delete another function.

 def delete_function(func):
    del func

is what I have so far, but for some reason it doesn't work.

def foo():
    print("foo")
delete_function(foo)

doesn't seem to do the trick. I know one can do it easily, just

del(foo)

but I'm trying to do it a different way. How?

4
  • 5
    what is the problem you hope to solve with this technique? Commented Apr 28, 2012 at 20:56
  • 1
    Indeed. Why, for the love of the code, why? Commented Apr 28, 2012 at 21:04
  • If you have to do this, there's probably something wrong with your implementation. Commented Apr 28, 2012 at 21:52
  • Joe Loo, if one of the answers you've been given actually answers your question -- mine or glglgl's saying "no, don't do this", or Omri's, giving a way to do it in some cases but that may do the Wrong Thing in others -- then you should accept whatever answer answers your question best. If not, you should edit your question to make it clearer what you think still needs answering. Commented May 2, 2012 at 9:08

4 Answers 4

17

Deleting a function isn't really something you do to the function itself; it's something you do to the namespace it lives in. (Just as removing the number 3 from a list isn't something you do to the number 3, it's something you do to the list.)

Suppose you say

def foo(x): return 1
bar = foo

Then (more or less) you have two names, foo and bar, for the exact same function. Now suppose you call delete_function(foo) or delete_function(bar). The exact same thing, namely a function object, is being passed to delete_function. But what you actually want to remove is the association between the name foo or bar and that object -- and there's no possible way delete_function (however you define it) can know whether it's foo or bar or something else you're wanting to get rid of.

(Well ... Actually, there is. There are nasty hacky things you can do that would let the code in delete_function know more about how it was called. But don't even think about thinking about them.)

So. Your options are as follows. (1) Nasty hacky things, as just mentioned. Don't. (2) Pass delete_function not the function object but information about the name of the function and the thing you're trying to delete it from. This is ugly and ungainly. (3) Don't bother.

I strongly recommend #3, unless the only reason you're doing this is to learn more about how Python works. In the latter case, a good place to begin might be http://docs.python.org/reference/executionmodel.html.

Sign up to request clarification or add additional context in comments.

Comments

11

Since foo is a global, you can delete it from the global definitions:

def delete_func(func):
    del globals()[func.func_name]

2 Comments

Too bad if the definition of func you were trying to delete was actually not in the global namespace. (E.g., because it's inside another function.)
@GarethMcCaughan Yes, this solution is only good for global functions (but I think my answer makes it pretty clear).
5

It just won't work.

What you are trying to do is, essentially, the name space of the caller.

Try this:

print "0", locals()
def foo(): pass
print "1", locals()
del foo
print "2", locals()

Note that

  1. the locals dict at 0 and 2 are identical, and at 1 nearly - except it has the additional assignment of foo.
  2. del is a statement and not a function

If you do the del in a function delete_function(), essentially the assignment within your function gets removed (which is effectless because the function is terminated immediately), while the caller keeps the assignment.

Strictly spoken, del does not delete objects, but merely assignments from names to objects. Objects get deleted "automatically" (garbage collected) as soon as they are not referenced any longer.

It COULD work what you try to do by inspection of the stack frame and passing of the name to be deleted as a string, but it would be a PITA.

Maybe you try

del locals()['foo']

or

locals()['foo'] = 42

? But I think it is not guarantteed that it really modifies the real locals dictionary, it might as well operate on a copy and thus stay effectless...

Comments

1

If you're using python 3, this should work:

def foo():
    return 'foo'

del foo

1 Comment

This is the simplest option and it was effective for me where the others were not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.