如何在 Python 中动态分配内存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38009008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to dynamically allocate memory in Python
提问by lb lb
Is there any method in python, that I can use to get a block of memory from the heap ,and use a variable to reference it. Just like the keyword "new" , or the function malloc()
in other languages:
python中是否有任何方法可以用来从堆中获取一块内存,并使用一个变量来引用它。就像关键字 "new" ,或malloc()
其他语言中的函数:
Object *obj = (Object *) malloc(sizeof(Object));
Object *obj = new Object();
In the project, my program is waiting to receive some data in uncertain intervals and with a certain length of bytes when correct.
在项目中,我的程序正在等待以不确定的时间间隔接收一些数据,并且在正确时接收一定长度的字节。
I used to it like this:
我以前是这样的:
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);
}
}
Now, I want to migrate these old project to python, and I tried to do it like this:
现在,我想将这些旧项目迁移到 python,我尝试这样做:
def reveive():
data=dataRecv()
globalList.append(data)
However, I get the all item in the list are same, and equal to the latest received item. It is obvious that all the list items are point to the same memory adress, and I want to get a new memory adress each the function is called.
但是,我得到列表中的所有项目都是相同的,并且等于最新收到的项目。很明显,所有列表项都指向相同的内存地址,我想在每次调用函数时获得一个新的内存地址。
回答by clocker
The equivalent of "new" in python is to just use a constructor eg:
python中“new”的等价物是只使用构造函数,例如:
new_list = list() # or [] - expandable heterogeneous list
new_dict = dict() # expandable hash table
new_obj = CustomObject() # assuming CustomObject has been defined
Since you are porting from C, some things to note. Everything is an object in python including integers, and most variables are just references, but the rules for scalar variables such as integers and strings are different from containers, eg:
由于您是从 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
However:
然而:
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']
You can pre-allocate sizes, if you'd like but it often doesn't buy you much benefit in python. The following is valid:
如果您愿意,您可以预先分配大小,但在 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
If you want to ensure memory leaks do not occur, use local variables as often as possible, eg, within a function so as things go out of scope you don't have to worry.
如果您想确保不发生内存泄漏,请尽可能多地使用局部变量,例如,在函数内,这样您就不必担心事情超出范围。
For efficient vectorized operations (and much lower memory footprint) use numpy arrays.
对于高效的矢量化操作(以及更低的内存占用),请使用 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
My added two cents: I'd probably start by asking what your primary goal is. There is the pythonic ways of doing things, while trying to optimize for speed of program execution or minimum memory footprint. And then there is the effort of trying to port a program in as little time as possible. Sometimes they all intersect but more often, you will find the pythonic way to be quick to translate but with higher memory requirements. Getting higher performance out of python will probably take focused experience. Good luck!
我加了两分钱:我可能会先问你的主要目标是什么。有 Pythonic 的做事方式,同时尝试优化程序执行速度或最小内存占用。然后是尝试在尽可能短的时间内移植程序。有时它们都相交,但更多时候,您会发现 Pythonic 方式可以快速翻译,但需要更高的内存要求。从 python 中获得更高的性能可能需要专注的经验。祝你好运!
回答by Viktor Engelmann
Keep in mind that interpreted languages usually don't flatten the types as compiled languages do. The memory layout is (probably) completely different than in the raw data. Therefore, you cannot simply cast raw data to a class instance or vice versa. You have to read the raw data, interpret it and fill your objects manually.
请记住,解释型语言通常不会像编译型语言那样扁平化类型。内存布局(可能)与原始数据完全不同。因此,您不能简单地将原始数据转换为类实例,反之亦然。您必须读取原始数据、解释它并手动填充您的对象。
回答by Basile Starynkevitch
You should read the Python tutorial.
您应该阅读Python 教程。
You can create lists, dictionaries, objects and closures in Python. All these live in the (Python) heap, and Python has a naive garbage collector(reference counting + marking for circularity).
您可以在 Python 中创建列表、字典、对象和闭包。所有这些都存在于 (Python) heap 中,并且 Python 有一个简单的垃圾收集器(引用计数 + 循环标记)。
(the Python GC is naive because it does not use sophisticated GC techniques; hence it is slower than e.g. Ocaml or many JVM generational copying garbage collectors; read the GC handbookfor more; however the Python GC is much more friendly to external C code)
(Python GC 是幼稚的,因为它不使用复杂的 GC 技术;因此它比 Ocaml 或许多 JVM 分代复制垃圾收集器慢;阅读GC 手册了解更多信息;但是 Python GC 对外部 C 代码更友好)