別の関数を削除する関数を作成しようとしています。
def delete_function(func):
del func
これまでのところ私が持っているものですが、何らかの理由で機能しません。
def foo():
print("foo")
delete_function(foo)
うまくいかないようです。簡単にできることはわかっています。
del(foo)
しかし、私はそれを別の方法でやろうとしています。どのように?
別の関数を削除する関数を作成しようとしています。
def delete_function(func):
del func
これまでのところ私が持っているものですが、何らかの理由で機能しません。
def foo():
print("foo")
delete_function(foo)
うまくいかないようです。簡単にできることはわかっています。
del(foo)
しかし、私はそれを別の方法でやろうとしています。どのように?
関数の削除は、実際には関数自体に対して行うことではありません。それは、それが存在する名前空間に対して行うことです。(リストから数字の 3 を削除することは、数字の 3 に対して行うことではなく、リストに対して行うことです。)
あなたが言うとします
def foo(x): return 1
bar = foo
次に、(多かれ少なかれ)まったく同じ関数に対してfoo
との 2 つの名前があります。ここで、またはbar
を呼び出すとします。まったく同じもの、つまり関数オブジェクトが に渡されます。しかし、実際に削除したいのは、名前orとそのオブジェクトの間の関連付けです。(どのように定義しても)削除したいオブジェクトがorまたは何か他のものであるかどうかを知る方法はありません。delete_function(foo)
delete_function(bar)
delete_function
foo
bar
delete_function
foo
bar
(うーん...実際にはあります。コードがどのように呼び出されたかをコードに知らせるためにできる厄介なハックがありますdelete_function
。しかし、それらについて考えることさえ考えないでください。)
そう。オプションは次のとおりです。(1) 今述べたように、厄介なハッキーなもの。しないでください。delete_function
(2)関数オブジェクトではなく、関数の名前と削除しようとしているものに関する情報を渡します。これは醜く、不格好です。(3) 気にしないでください。
これを行う唯一の理由が Python の仕組みについてもっと学ぶことでない限り、 #3 を強くお勧めします。後者の場合、開始するのに適した場所はhttp://docs.python.org/reference/executionmodel.htmlです。
はグローバルであるためfoo
、グローバル定義から削除できます。
def delete_func(func):
del globals()[func.func_name]
それはうまくいきません。
あなたがやろうとしているのは、本質的に、呼び出し元の名前空間です。
これを試して:
print "0", locals()
def foo(): pass
print "1", locals()
del foo
print "2", locals()
ご了承ください
foo
.del
はステートメントであり、関数ではありませんdel
関数内でを実行するとdelete_function()
、本質的に関数内の割り当てが削除されます (関数はすぐに終了するため効果がありません) が、呼び出し元は割り当てを保持します。
厳密にdel
は、オブジェクトを削除するのではなく、名前からオブジェクトへの割り当てのみを行います。オブジェクトは、参照されなくなるとすぐに「自動的に」削除されます (ガベージ コレクション)。
スタックフレームを検査し、削除する名前を文字列として渡すことで、何をしようとしても機能する可能性がありますが、それは PITA になります。
多分あなたは試します
del locals()['foo']
また
locals()['foo'] = 42
? しかし、それが実際のローカル辞書を実際に変更することは保証されていないと思います。コピーを操作して、効果がないままにすることもできます...