如何在Python

时间:2016-06-24 08:36:14

标签: python memory heap

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)

但是,我得到列表中的所有项目都相同,并且等于最新收到的项目。很明显,所有列表项都指向相同的内存地址,并且我希望每个函数都被调用一个新的内存地址。

3 个答案:

答案 0 :(得分:2)

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

我加了两分钱: 我可能会先问你的主要目标是什么。在尝试优化程序执行速度或最小内存占用时,有pythonic做事方式。然后尝试在尽可能短的时间内移植程序。有时候它们都相交但更常见的是,你会发现pythonic的方式可以快速翻译,但需要更高的内存。从python中获得更高的性能可能需要专注的经验。 祝你好运!

答案 1 :(得分:1)

您应该阅读Python tutorial

您可以在Python中创建列表,词典,对象和闭包。所有这些都存在于(Python)heap中,Python有一个天真的garbage collector(引用计数+圆形标记)。

(Python GC很天真,因为它不使用复杂的GC技术;因此它比Ocaml或许多JVM代数复制垃圾收集器慢;请阅读GC handbook以获取更多信息;但是Python GC对外部C代码更加友好)

答案 2 :(得分:0)

请记住,解释型语言通常不会像编译语言那样压缩类型。内存布局(可能)与原始数据完全不同。因此,您不能简单地将原始数据转换为类实例,反之亦然。您必须阅读原始数据,解释原始数据并手动填充对象。