13

c/c++ では、関数内でローカル変数を作成すると、変数がスタックに含まれます。

http://effbot.org/zone/call-by-object.htm

CLU オブジェクトは、プロシージャーの起動とは関係なく存在します。オブジェクト用のスペースは動的ストレージ領域から割り当てられます /.../ 理論上、すべてのオブジェクトは永遠に存在し続けます。実際には、オブジェクトがどの CLU プログラムからもアクセスできなくなったときに、そのオブジェクトによって使用されたスペースを再利用することができます。

これは、Python のオブジェクトがヒープから作成されることを意味しますか (c/c++ の malloc のように)? オブジェクトに関連付けられた名前がない場合、オブジェクトの割り当てが解除されますか?(スマートポインターなど)?

例:

def foo(a): 
  result = []
  result.append(a)
  return result

foo("hello")

myList = foo("bye")

最初の結果 ([]) はヒープに作成され、名前が関連付けられていないため、割り当てが解除されましたか?

4

3 に答える 3

18

はい、すべてのPythonオブジェクトはヒープ上に存在します(少なくともCPython上では)。それらは参照カウントされます。オブジェクトへの最後の参照が消えると、割り当てが解除されます。(CPythonには、サイクルを中断するためのガベージコレクターもあります。)

CPythonでは、戻り値を名前にバインドせず、参照カウントがゼロに低下したため、関数が戻るとすぐに最初のリストが表示されなくなります。他の実装では、ガベージコレクターが起動するまでオブジェクトの寿命が長くなる場合があります。

一部のオブジェクト(開いているファイルなど)には、オブジェクトの割り当てが解除されたときに自動的に解放されるリソースが添付されていますが、上記の理由から、これに依存することはお勧めしません。リソースを使い終わったら、リソースを明示的に閉じる必要があります。

于 2012-07-27T13:25:48.880 に答える
6

はい、CPythonのすべての値はヒープに割り当てられ、それらの割り当てを解除するタイミングを知るために参照カウントされます。Cとは異なり、ほとんどの場合、値がその関数よりも長持ちするかどうかを知る方法はありません。したがって、安全な方法は、すべてをヒープに割り当てることだけです。

確かに、いくつかの分析を行って、特定の値が関数に渡されないためにエスケープできないことを確認できますが、Pythonでの使用は限られており、余分なオーバーヘッドはおそらく価値がありません。

于 2012-07-27T13:26:12.950 に答える
6

他の回答の補足として、特別な方法を使用して、ガベージコレクションがいつ発生したかを追跡する1つの方法を次に示し__del__ます。

class Test(object):
    def __init__(self, name):
        self.name = name

    def __del__(self):
        print "deleting {0}".format(self.name)

print "discarded instance creation"
Test("hello")

print "saved instance creation"
myList = Test("bye")

print "program done"

出力:

破棄されたインスタンスの作成
ハローの削除
保存されたインスタンスの作成
プログラム終了
さようならを削除する

より詳細なデータについては、gc モジュールを参照してください。

于 2012-07-27T13:31:01.870 に答える