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

次に、(多かれ少なかれ)まったく同じ関数に対してfooとの 2 つの名前があります。ここで、またはbarを呼び出すとします。まったく同じもの、つまり関数オブジェクトが に渡されます。しかし、実際に削除したいのは、名前orとそのオブジェクトの間の関連付けです。(どのように定義しても)削除したいオブジェクトがorまたは何か他のものであるかどうかを知る方法はありません。delete_function(foo)delete_function(bar)delete_functionfoobardelete_functionfoobar

(うーん...実際にはあります。コードがどのように呼び出されたかをコードに知らせるためにできる厄介なハックがありますdelete_function。しかし、それらについて考えることさえ考えないでください。)

そう。オプションは次のとおりです。(1) 今述べたように、厄介なハッキーなもの。しないでください。delete_function(2)関数オブジェクトではなく、関数の名前と削除しようとしているものに関する情報を渡します。これは醜く、不格好です。(3) 気にしないでください。

これを行う唯一の理由が Python の仕組みについてもっと学ぶことでない限り、 #3 を強くお勧めします。後者の場合、開始するのに適した場所は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 に答える