简体   繁体   English

Python中的C风格指针,这是正确的吗?

[英]C-style pointer in Python, is this correct?

I'm trying to port a C application to Python, and there are a lot of pointers. 我正在尝试将C应用程序移植到Python,并且有很多指针。 Are these equal: 这些是平等的:

obj->position = (float*) malloc(obj->totalItems * obj->xyz * sizeof (float));
for (i = 0; i < components; i++) {
    obj->comps[i].position = obj->position + obj->pOffset; // Pointer arithmetic
obj->pOffset += obj->comps[i].items * obj->xyz;
}

And

for i in range(self.totalItems * self.xyz):
    self.position.append(0.0)
for i in range(self.components):
    self.comps[i].position = self.position[self.pOffset:] # Position was a C pointer
    self.pOffset += self.comps[i].items * self.xyz

I know that Python objects are passed by reference, so I'm wondering if: 我知道Python对象是通过引用传递的,所以我想知道是否:

self.comps[N].position = [1,2,3,4]

will change some part of: 将改变以下部分内容:

self.position[]

Maybe something like this: 也许是这样的:

self.position = [0.0 for _ in self.total_items * self.xyz]
for i in range(self.components):
    self.comps[i].position = self.p_offset
    self.p_offset += self.comps[i].items

In Python, you can change values inside a class instance variable. 在Python中,您可以更改类实例变量中的值。 This is called "mutating" the instance. 这被称为“变异”实例。 If the class doesn't allow this, it is an "immutable" class; 如果类不允许这样,它就是一个“不可变”的类; if it does allow this, it is a "mutable" class. 如果确实允许这样做,它就是一个“可变”类。 Strings are immutable, as are integers, but lists are mutable. 字符串是不可变的,整数也是如此,但列表是可变的。

In Python, there is no way that I can think of to get a reference to the middle part of a list. 在Python中,我无法想到获得对列表中间部分的引用。 Lists are mutable: things can be inserted, deleted, etc. What should the reference do then? 列表是可变的:可以插入,删除等等。参考应该做什么?

So instead of doing pointer math and storing a reference to a spot within a list, you should just store the offset, and then use the offset to index the list when you need to reference that spot in the list. 因此,不应该使用指针数学并存储对列表中某个点的引用,而应该只存储偏移量,然后在需要引用列表中的那个点时使用偏移量来索引列表。

For your specific question: 针对您的具体问题:

self.comps[N].position = [1,2,3,4]

This would rebind the name position inside the self.comps[N] object to now point to a newly created list instance with the value [1, 2, 3, 4] and would not affect self.position at all. 这将重新绑定self.comps[N]对象中的名称position ,现在指向一个新创建的列表实例,其值为[1, 2, 3, 4]并且根本不会影响self.position However, if you just set self.comps[i].position to index values you could use this code: 但是,如果您只是将self.comps[i].position为索引值,则可以使用以下代码:

i = self.comps[N].position
lst = [1, 2, 3, 4]
self.position[i:i+len(lst)] = lst

This would use a "slice" into the self.position list to replace the values. 这将在self.position列表中使用“切片”来替换值。

Note that if you use SciPy or even just NumPy, you can define a numpy.array which is not dynamic; 请注意,如果您使用SciPy甚至只使用NumPy,您可以定义一个非动态的numpy.array ; and you can use "views" to get a reference to just part of the list. 并且您可以使用“views”来获取对列表的一部分的引用。 You might want to look into that, especially if you are working with really large arrays or matrices. 您可能想要研究一下,特别是如果您正在使用非常大的数组或矩阵。

View onto a numpy array? 查看numpy阵列?

self.comps[N].position = [1,2,3,4] self.comps [N] .position = [1,2,3,4]

will set self.comps[N].position to be a new list. 将self.comps [N] .position设置为新列表。 If there are other references to the old list that was self.comps[N].position, they will not be changed. 如果对旧列表的其他引用是self.comps [N] .position,则不会更改它们。

Example

x=[1,2,3]
y=x
print y #[1, 2, 3]
x[1]=4
print y #[1, 4, 3]
x=[4,5,6]
print y #[1, 4, 3]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM