12

我正在尝试创建一个函数来删除另一个函数。

 def delete_function(func):
    del func

是我到目前为止所拥有的,但由于某种原因它不起作用。

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

似乎没有奏效。我知道一个人可以很容易地做到这一点,只是

del(foo)

但我正在尝试以不同的方式来做这件事。如何?

4

4 回答 4

16

删除一个函数并不是你对函数本身做的事情。这是你对它所在的命名空间所做的事情。(就像从列表中删除数字 3 不是你对数字 3 所做的事情,这是你对列表所做的事情。)

假设你说

def foo(x): return 1
bar = foo

然后(或多或少)你有两个名字,foobar,对于完全相同的功能。现在假设您调用delete_function(foo)or delete_function(bar)完全相同的东西,即一个函数对象,被传递给delete_function. 但是您真正想要删除的是名称foobar与该对象之间的关联——并且没有可能的方法delete_function(无论您如何定义它)可以知道它是您想要删除的还是其他东西foobar

(嗯......实际上,有。你可以做一些令人讨厌的hacky事情,让代码delete_function知道更多关于它是如何被调用的。但甚至不要考虑考虑它们。)

所以。您的选择如下。(1) 刚才提到的讨厌的东西。不。(2) 传递delete_function的不是函数对象,而是有关函数名称和您要从中删除它的事物的信息。这是丑陋和笨拙的。(3) 不要打扰。

我强烈推荐#3,除非你这样做的唯一原因是更多地了解 Python 的工作原理。在后一种情况下,一个好的起点可能是http://docs.python.org/reference/executionmodel.html

于 2012-04-28T20:57:34.527 回答
11

由于foo是全局变量,您可以将其从全局定义中删除:

def delete_func(func):
    del globals()[func.func_name]
于 2012-04-28T20:58:04.607 回答
5

它只是行不通。

本质上,您要做的是调用者的名称空间。

试试这个:

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

注意

  1. 0 和 2 处的当地人 dict 是相同的,而 1 处几乎是相同的 - 除了它有foo.
  2. del是语句而不是函数

如果你del在函数中执行delete_function(),基本上你的函数中的赋值被删除(这是无效的,因为函数立即终止),而调用者保留赋值。

严格来说,del不会删除对象,而只是从名称到对象的赋值。一旦不再引用对象,它们就会被“自动”删除(垃圾收集)。

它可以通过检查堆栈帧并将要删除的名称作为字符串传递来完成您尝试执行的操作,但它将是一个 PITA。

也许你试试

del locals()['foo']

或者

locals()['foo'] = 42

? 但我认为它并不能保证它真的修改了真正的本地人字典,它还不如对副本进行操作,从而保持无效......

于 2012-04-28T20:54:20.810 回答
1

如果您使用的是 python 3,这应该可以工作:

def foo():
    return 'foo'

del foo
于 2020-07-21T20:10:08.157 回答