2012-04-28 202 views
8

我試圖創建一個函數來刪除另一個函數。刪除功能

def delete_function(func): 
    del func 

是我到目前爲止,但由於某種原因它不起作用。

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

似乎沒有辦法。我知道一個人可以很容易地做到這一點,只是

del(foo) 

但我試圖做一個不同的方式。怎麼樣?

+5

什麼是你希望用這種方法來解決這個問題? – SingleNegationElimination 2012-04-28 20:56:49

+1

確實。爲什麼爲了代碼的愛,爲什麼? – Macke 2012-04-28 21:04:41

+0

如果你必須這樣做,你的實現可能有問題。 – 2012-04-28 21:52:47

回答

13

刪除函數並不是您對函數本身所做的事情;這是你對它所在的命名空間做的事情。(就像從列表中刪除數字3不是你對數字3所做的事情,這是你對列表做的事情。)

假設你說

def foo(x): return 1 
bar = foo 

然後(或多或少),您有兩個名稱foobar,其功能完全相同。現在假設您致電delete_function(foo)delete_function(bar)完全相同的東西,即函數對象,正在傳遞給delete_function。但是你實際上想要刪除的是名稱foobar與該對象之間的關聯 - 並且沒有可能的方法delete_function(但是您可以定義它)可以知道它是foo還是bar或您想要擺脫的其他內容的。

(呃......實際上,有一些令人討厭的黑客行爲可以讓delete_function中的代碼知道更多關於它是如何被調用的,但是甚至都沒有考慮過關於它們的想法。)

所以。您的選擇如下。 (1)正如剛纔提到的那樣,討厭的哈克東西。別。 (2)通過delete_function不是函數對象,而是關於函數名稱和您試圖從中刪除它的信息。這是醜陋而不好看的。 (3)不要打擾。

我強烈建議#3,除非這樣做的唯一原因是要了解有關Python如何工作的更多信息。在後一種情況下,開始的好地方可能是http://docs.python.org/reference/executionmodel.html

4

它只是不會工作。

你所要做的就是調用者的名字空間。

試試這個:

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

注意

  1. 當地人快譯通在0和2是相同的,並且在近1 - 除了它的foo額外的任務。
  2. del是一個聲明,而不是一個功能

如果你在一個函數delete_function()del,基本上在函數中的分配被刪除(因爲該功能將被立即終止這是effectless),同時主叫方保持作業。

嚴格地說,del不會刪除對象,而只是從名稱到對象的賦值。只要對象不再被引用,對象就會自動刪除(垃圾收集)。

它可以工作你試圖通過檢查棧框架和傳遞的名稱被刪除作爲一個字符串,但它會是一個PITA。

也許你試着

del locals()['foo'] 

locals()['foo'] = 42 

?但我認爲它不能保證它確實修改了真正的當地人字典,它可能會在副本上運行並因此保持無效...

7

由於foo是一個全球性的,可以從全局定義中刪除:

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

+1這就像是最簡單的解決方案。 – 2012-04-28 21:03:24

+5

如果您嘗試刪除的'func'的定義實際上不在全局名稱空間中,那就太糟糕了。 (例如,因爲它在另一個函數中。) – 2012-04-28 21:13:07

+0

@GarethMcCaughan是的,這個解決方案只適用於全局函數(但我認爲我的答案很清楚)。 – 2012-04-28 21:36:49