作成した変数や関数などをインタプリタのメモリから削除する方法はありますか?


113

私はこの質問に対する正確な答えを数日間探し続けてきましたが、良いことは何もありません。私はプログラミングの完全な初心者ではありませんが、中級レベルではまだです。

Pythonのシェルにいるときは、次のように入力dir()します。現在のスコープ(メインブロック)にあるすべてのオブジェクトのすべての名前が表示されますが、そのうちの6つがあります。

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

次に、たとえば変数を宣言すると、x = 10組み込みモジュールの下のオブジェクトのリストに自動的に追加され、もう一度dir()入力dir()すると、次のように表示されます。

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']

関数、クラスなどについても同様です。

最初に利用可能な標準6を消去せずに、これらの新しいオブジェクトをすべて削除するにはどうすればよいですか?

コマンドプロンプトウィンドウからすべてのテキストを消去する「メモリクリーニング」、「コンソールのクリーニング」についてここで読みました。

>>> import sys
>>> clear = lambda: os.system('cls')
>>> clear()

しかし、これはすべて、私が達成しようとしていることとは何の関係もありません。使用されているオブジェクトをすべて削除するわけではありません。


2
なぜあなたはこれをする必要があると思いますか、それとも単に好奇心から求めているのですか?
PM 2Ring 2014年

そこにdel機能があることを知りませんでした。私はPythonを習得し始め、シェルで実験するx必要yがあることが多いので、またはのような標準変数名は既に使用されており、シェルを再起動するにはさらに15秒かかります(今、非常に古いラップトップを持っています)。そこで、Pythonのメモリをより早くクリーンアップする方法を見つけたかったのです。
funghorn 2014年

1
ああ。FWIW delは、正確には関数ではないため、no ()です。デルの声明を紹介するキーワードです。もちろん、...それは実際にオブジェクトが機能を伴うことが削除されますが、それはまた別の話だか
PM 2Ring

あなたがそれらを使用しているのでない限り、シェル名で実験するとき、xまたはy使用すべきではない または、あなたがのような愚かなことをしない限り、あらゆる種類のゴミが場所に散らばってしまうでしょう。:)from _somemodule_ import *
PM 2Ring 2014年

1
私はこの質問に自分の方法をググって、今疑問に思っています-とにかくすべての変数と関数を削除したい場合、なぜカーネルを再起動してスクリプトを最初から再実行できないのですか?
vagabond 2017

回答:


159

あなたは個々の名前を削除することができますdel

del x

または、globals()オブジェクトから削除することもできます。

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

これは単なるループの例です。これは、アンダースコアで始まらない名前のみを防御的に削除し、インタープリターの最初にアンダースコアのない名前のみを使用したという(無理のない)仮定を行います。本当に徹底したい場合は、ハードコーディングされた名前のリストを使用して、代わりに保持することができます(ホワイトリスト)。インタープリターを終了して再起動する以外に、クリアを実行する組み込み関数はありません。

インポートしたモジュール(import os)は、によって参照されるため、インポートされたままになりsys.modulesます。以降のインポートでは、すでにインポートされているモジュールオブジェクトが再利用されます。現在のグローバル名前空間では、それらへの参照がありません。


まあ、私はstartswith('_')かなり素朴なようだと言わざるを得ません。誰かが書き込むためのスマート十分にある場合_foo=42でも、あるいは__foo__=42、どのように我々は、これらを削除することができますか?プログラムで標準モジュールのプロパティ名を取得する方法はありますか?
georg 2014年

2
@georg:防御的にループをコーディングしました。改善したい場合は、保持する名前の初期リストをハードコーディングする必要があります。
Martijn Pieters

だから、どうしよう?私の考えでしたdir(ModuleType())が、それだけで返すdocname
georg、2014年

1
@georg:いいえ。インタプリタのグローバル名前空間もリリースごとに異なり、後の段階でインタプリタを開いたときにそこにあったものを列挙するための絶対的な方法(私が知っていること)はありません。
Martijn Pieters

1
@nakE関数とクラスは、他のオブジェクトと同様、単なるオブジェクトです。それらは特別ではありません。ホワイトリストを使用するか、クラスと関数を保持するために必要なオブジェクトタイプを確認してください。
Martijn Pieters

67

はい。iPythonですべてを削除する簡単な方法があります。iPythonコンソールで、次のように入力します。

%reset

次に、システムが確認を求めます。yを押します。このプロンプトを表示したくない場合は、次のように入力します。

%reset -f

これは動作するはずです。


1
もう一度、なぜこれが一番の答えではないのですか?
myradio

11
@myradio IPythonを使用していないすべての人には無関係であり、質問にも答えません。この質問では、IPython シェルのコンテンツをリセットするのではなく、グローバルオブジェクト参照を削除する方法を尋ねます。
Andreas

17

Pythonガベージコレクターを使用できます。

import gc
gc.collect()

6
@Fardinさん、こんにちは!ありがとう!あなたの答えは仕事をしてくれて、私の日を救った!しかし、gc.collect()の前に、del(variable)を実行しました。
Gmosy Gnaq 2018

9

のようなインタラクティブな環境にいるJupyter場合やipython不要なvarが重くなっている場合にそれらをクリアすることに興味があるかもしれません 。

マジック・コマンドresetreset_selective同様、Pythonの対話セッションで利用できるである ipythonJupyter

1) reset

reset 引数なしで呼び出された場合、ユーザーが定義したすべての名前を削除して名前空間をリセットします。

inそして、outパラメータは、イン/アウトのキャッシュをフラッシュするかどうかを指定します。ディレクトリ履歴はdhistパラメータでフラッシュされます。

reset in out

別の興味深いものはarray、numpy配列のみを削除することです。

reset array

2)reset_selective

ユーザーが定義した名前を削除して名前空間をリセットします。入出力履歴は、必要な場合に備えて残されます。

クリーンなアレイの例:

In [1]: import numpy as np
In [2]: littleArray = np.array([1,2,3,4,5])
In [3]: who_ls
Out[3]: ['littleArray', 'np']
In [4]: reset_selective -f littleArray
In [5]: who_ls
Out[5]: ['np']

出典:http : //ipython.readthedocs.io/en/stable/interactive/magics.html


6

これでうまくいきました。

グローバルに続いてローカルで2回実行する必要があります

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

for name in dir():
    if not name.startswith('_'):
        del locals()[name]

4

実際には、Pythonはもう使用されていないメモリを回収します。これはガベージコレクションと呼ばれ、Pythonでは自動プロセスです。しかし、それでもしたい場合は、で削除できますdel variable_name。また、変数をNone

a = 10
print a 

del a       
print a      ## throws an error here because it's been deleted already.

参照されていないPythonオブジェクトからメモリを完全に解放する唯一の方法は、ガベージコレクターを使用することです。delキーワードはオブジェクトから名前をアンバインドするだけですが、オブジェクトはガベージコレクションされる必要があります。gcモジュールを使用してガベージコレクターを強制的に実行できますが、これはほぼ確実に時期尚早の最適化ですが、独自のリスクがあります。delそれらの名前はいずれにしても範囲外になったため削除されていたため、使用しても実際には効果がありません。


確かに。もちろん、インタープリターのグローバル名前空間名で作業しているときは、スコープ外にはなりませんが、そうです。:)私はそれがゴミ実装依存で収集されたオブジェクトによって使用されるメモリに起こるが、ほとんどのPython実装でgc'edメモリは単にPythonのプールに戻って何、それはだということにも言及する価値だと思うではないに戻りましたプログラムが終了するまでOS。
PM 2Ring 2014年

@ PM2Ring LOL :)そう思います。どこからPythonを参照しますか?
d-coder

2
CPythonでは、GCは参照サイクルを解除するためにのみ必要であることに注意してください。参照が残っていない場合、オブジェクトメモリからインスタ削除されます。だから、del 、ここで本当の効果を持っています。
Martijn Pieters

@ MartijnPieters、insta-removed?それは専門用語ですか?:)
Eryk Sun 2014

2
@eryksun:はい、もちろんRFC 4042-bis2で定義されています!:-P
Martijn Pieters
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.