2

我正在尝试创建一个填充结构化数据项列表的类,以及一些用于从文件和 IO 设备填充列表的方法。

我的方法存在问题,该方法填写了一个新的数据结构并将其附加到一个列表中。它被设置为一个协程,用来自 (yield) 函数的数据填充一个临时结构。完成后,它将数据附加到列表中(例如 self.list.append(newdata))。我的问题是这个附加是通过引用发生的,我不知道如何将 newdata 初始化到新的内存空间。最终发生的是我有一个数据列表都指向相同的数据结构(例如“myclass.list[n] is myclass.list[m]”总是产生 TRUE)。谁能告诉我如何使这项工作?

如果我用 C++ 编写,我只需要执行“newdata = new * mydatastructure;” 在每次循环迭代之后......我只是无法弄清楚如何在python中做到这一点......我在这里偏离路线了吗?

4

2 回答 2

3

new是语法糖mydatastructure* = malloc(sizeof(mydatastructure));(或类似的东西,已经有一段时间了)。它会在堆上为您拥有的东西分配适当数量的内存,如果您使用构造函数(在 C++ 中),它会初始化内存。

Python 会为您解决这个问题。从技术上讲,Python 中有一个类似的例程,称为__new__,它控制分配。但是,您很少需要在对象上覆盖它。

Python 对象的构造函数称为__init__. 当你调用时__init____new__实际上是先调用。所以,当你在 Python 中构造对象时,你会自动为它们分配新的内存,而且每一个都是不同的。正如 Benjamin 所指出的,构造函数语法 ( foo = Foo()) 是您__init__无需实际键入即可调用的方式__init__()

不幸的是,您的问题出在代码的其他地方。

顺便说一句,如果你真的想确定两个变量引用同一个对象,你可以使用id()函数来获取引用号。关键字比较这些is参考编号,与使用对象方法比较它们的==运算符相反。__eq__

于 2013-08-05T18:46:18.717 回答
2

我的问题是这个附加是通过引用发生的,我不知道如何将 newdata 初始化到新的内存空间。

如果您尝试按值将对象附加到列表中,则可能需要使用copy.copy 或 copy.deepcopy 之类的东西来确保复制附加的内容。

>>> # The Problem
>>> class ComplexObject:
...     def __init__(self, herp, derp):
...         self.herp = herp
...         self.derp = derp
...
>>> obj = ComplexObject(1, 2)
>>> list = []
>>> list.append(obj)
>>> obj.derp = 5
>>> list[0].derp
5
>>> # obj and list[0] are the same thing in memory
>>> obj
<__main__.ComplexObject instance at 0x0000000002243D48>
>>> list[0]
<__main__.ComplexObject instance at 0x0000000002243D48>
>>> # The solution
>>> from copy import deepcopy
>>> list = []
>>> obj = ComplexObject(1,2)
>>> list.append(deepcopy(obj))
>>> obj.derp = 5
>>> list[0].derp
2
>>> obj
<__main__.ComplexObject instance at 0x0000000002243D48>
>>> list[0]
<__main__.ComplexObject instance at 0x000000000224ED88>

这是我在没有看到任何代码的情况下从您的描述中实际解决您的问题的尝试。如果您对 Python 中的分配/构造函数更感兴趣,请参阅另一个答案。

于 2013-08-05T18:26:46.353 回答