web-dev-qa-db-ja.com

Pythonでメモリを動的に割り当てる方法

ヒープからメモリのブロックを取得し、変数を使用してそれを参照するために使用できるPythonのメソッドはありますか?キーワード「new」、または他の言語の関数malloc()と同じように:

Object *obj = (Object *) malloc(sizeof(Object)); 
Object *obj = new Object();

プロジェクトでは、私のプログラムは、不確実な間隔で、正しい場合は特定のバイト長でいくつかのデータを受信するのを待っています。

私はこれに次のように慣れていました:

void receive()// callback
{
  if(getSize()<=sizeof(DataStruct))
  {
   DataStruct *pData=malloc(sizeof(DataStruct));
   if(recvData(pData)>0)
   list_add(globalList,pData);
  }   
}

void worker()
{
  init()
  while(!isFinish)
 {
  dataProcess(globalList);
 }

}

今、私はこれらの古いプロジェクトをpythonに移行したいと思います、そして私はそれを次のようにしようとしました:

def reveive():
 data=dataRecv()
 globalList.append(data)

ただし、リスト内のすべてのアイテムは同じであり、最後に受信したアイテムと同じです。すべてのリスト項目が同じメモリアドレスを指していることは明らかであり、関数が呼び出されるたびに新しいメモリアドレスを取得したいと思います。

5
lb lb

pythonの "new"に相当するのは、コンストラクターを使用することです。例:

new_list = list() # or [] - expandable heterogeneous list
new_dict = dict() # expandable hash table
new_obj = CustomObject() # assuming CustomObject has been defined

Cから移植しているので、注意すべき点がいくつかあります。すべてが整数を含むpythonのオブジェクトであり、ほとんどの変数は単なる参照ですが、整数や文字列などのスカラー変数のルールはコンテナとは異なります。例:

a = 2   # a is a reference to 2
b = a   # b is a reference to 'a'
b = 3   # b now points to 3, while 'a' continues to point to 2

しかしながら:

alist = ['eggs', 2, 'juice']  # alist is reference to a new list
blist = alist # blist is a reference; changing blist affects alist
blist.append('coffee') # alist and blist both point to 
                       # ['eggs', 2, 'juice', 'coffee']

必要に応じてサイズを事前に割り当てることができますが、Pythonではあまりメリットがありません。以下が有効です。

new_list4k = [None]*4096 # initialize to list of 4096 None's 
new_list4k = [0]*4096    # initialize to 4096 0's
big_list = []
big_list.extend(new_list4k) # resizes big_list to accomodate at least 4k items

メモリリークが発生しないようにする場合は、ローカル変数をできるだけ頻繁に使用します。たとえば、関数内で、スコープ外になることを心配する必要はありません。

効率的なベクトル化された操作(およびはるかに低いメモリフットプリント)には、numpy配列を使用します。

import numpy as np
my_array = np.zeros(8192) # create a fixed array length of 8K elements
my_array += 4             # fills everything with 4

私が追加した2セント:私はおそらくあなたの主な目標が何であるかを尋ねることから始めるでしょう。プログラムの実行速度や最小のメモリフットプリントを最適化しようとしながら、Pythonの方法で物事を行うことができます。そして、できるだけ短い時間でプログラムを移植しようとする努力があります。それらがすべて交差することもありますが、より頻繁に、Pythonicの方法ですばやく翻訳できますが、メモリ要件が高くなります。 pythonからより高いパフォーマンスを得るには、おそらく集中的な経験が必要です。頑張ってください!

4
clocker

Pythonチュートリアル を読む必要があります。

Pythonでリスト、辞書、オブジェクト、クロージャを作成できます。これらはすべて(Python) heap にあり、Pythonにはナイーブ ガベージコレクター (参照カウント+循環性のマーキング)があります。

(Python GCは、高度なGC技術を使用しないため、単純です。したがって、Ocamlや多くのJVM世代別コピーガベージコレクターよりも低速です。 GCハンドブック をお読みください。詳細については、ただしPython GCは外部Cコードに対してはるかに使いやすい)

インタープリター型言語は通常、コンパイル型言語のように型をフラット化しないことに注意してください。メモリレイアウトは(おそらく)生データとは完全に異なります。したがって、生データをクラスインスタンスに単純にキャストしたり、その逆を行ったりすることはできません。生データを読み取り、解釈して、オブジェクトを手動で入力する必要があります。

0