Python属性和numpy数组 [英] Python attributes and numpy arrays

查看:97
本文介绍了Python属性和numpy数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存储一些属性的类.这些属性是numpy数组,内部有一些浮点数.我希望在创建对象时可以访问此属性.我不希望对包含属性值的外部变量执行任何操作来修改它们.

I have a class that stores some attributes. These attributes are numpy arrays with some floats inside. I want this attributes to be accessed when creating objects. What I don't want is them to be modified if any operation is done to a external variable that holds the value of the attribute.

这很容易与其他类型的变量的getter/setter或属性一起使用,但是对于numpy数组似乎失败.

This is simple to do with getters/setters or properties with other types of variables, but it seems to fail with numpy arrays.

我写了一个简单的脚本来测试我所知道的每种可能的解决方案.它适用于整数属性,但不适用于numpy数组.

I have wrote a simple script that tests every kind of possible solution I know. It works for integer attributes but fails with numpy arrays.

这是测试类:

class test_class:

    # Initialization
    def __init__(self, attribute1, attribute2, attribute3):

        self.attribute1 = attribute1
        self._attribute2 = attribute2
        self._attribute3 = attribute3

# Attribute 1 with getter and setter
    def get_attr1(self):
        return(self.attribute1)

    def set_attr1(self, value):
        self.attribute1 = value

    # Attribute 2 as a property with getter and setter
    def get_attr2(self):
        return(self._attribute2)

    def set_attr2(self, value):
        self._attribute2 = value

    attribute2 = property(get_attr2, set_attr2)

    # Attribute 3 as a property
    @property
    def attribute3(self):
        return(self._attribute3)

    @attribute3.setter
    def attribute3(self, value):
        self._attribute3 = value

使用整数作为属性对其进行测试:

Testting it with integers as attributes:

test = test_class(10, 100, 1000)

print test.get_attr1()
print test.attribute2
print test.attribute3

a1 = test.get_attr1()
a2 = test.attribute2
a3 = test.attribute3

a1 += 5
a2 += 50
a3 += 500

print test.get_attr1()
print test.attribute2
print test.attribute3

按预期输出,而无需在外部修改属性:

Output as expected, without the attributes being modified externally:

10
100
1000
10
100
1000

使用numpy数组对其进行测试:

Testing it with numpy arrays:

import numpy as np

test = test_class(np.array([10,20,30]), np.array([100,200,300]),   np.array([1000,2000,3000]))

print test.get_attr1()
print test.attribute2
print test.attribute3

a1 = test.get_attr1()
a2 = test.attribute2
a3 = test.attribute3

a1 += 5
a2 += 50
a3 += 500

print test.get_attr1()
print test.attribute2
print test.attribute3

输出与预期不符,值已更改:

Output not as expected, the values have been changed:

[10 20 30]
[100 200 300]
[1000 2000 3000]
[15 25 35]
[150 250 350]
[1500 2500 3500]

因此,如果没有getter/setters或属性不能与numpy数组一起使用,那该怎么办?

So if not getters/setters nor properties work with numpy arrays, what can be done?

好吧,我找到了使用copy.deepcopy函数解决此问题的方法.现在它可以正常工作了.

Well, I found a solution to this problem using the copy.deepcopy function. Now it works as expected.

属性定义:

from copy import deepcopy

class test_class:

    ...

    # Attribute 4 with getter and setter using deepcopy
    def get_attr4(self):
        return(deepcopy(self.attribute4))

    def set_attr4(self, value):
        self.attribute4 = value

测试:

test = test_class(np.array([10,20,30]), np.array([100,200,300]), np.array([1000,2000,3000]), np.array([10000,20000,30000]))

...
print test.get_attr4()
...
a4 = test.get_attr4()
...
a4 += 5000
...
print test.get_attr4()

结果:

...
[10000 20000 30000]
...
[10000 20000 30000]

推荐答案

NumPy数组是可变的,整数不是.

NumPy arrays are mutable, integers are not.

>>> a = 1
>>> id(1)
4297261152
>>> a += 1
>>> id(a)
4297261184

注意:id更改.

相对于:

>>> arr = np.arange(5)
>>> d(arr)
4331954736
>>> arr += 10
>>> id(arr)
4331954736
>>> arr
array([10, 11, 12, 13, 14])

注意:id保持不变.

使用a = test.get_attr1()a = test.attribute2都没关系.您获得的a是一个Python对象,因为几乎所有内容都是您在Python中处理的对象.一旦有了a,无论是通过赋值a = 1还是作为方法a = test.get_attr1()的返回值创建它的方式都无所谓(该属性只是为方法调用提供了更好的语法.).然后a只是对象的名称,您可以使用该对象.如果像NumPy数组一样易变,则+=通常会更改内部的值.对于不可变,这根本不可能.

It does not matter that you use a = test.get_attr1() or a = test.attribute2. The a you get is a Python object, as pretty much everything is an object you deal with in Python. Once you have a it does not matter how you created it either by assignment a = 1 or as return value from a method a = test.get_attr1() (The property just makes for a nicer syntax for a method call.). Then a is just a name for an object and you work with this object. If it is mutable like NumPy arrays the += typically changes the values inside. For immutable this simply not possible.

如果您不想修改这些对象,则可以将其复制.通常在模块copy的帮助下. NumPy数组提供了自己的复制方法:

If you do not want to modify these objects, you can male a copy. Usually with the help of the module copy. NumPy arrays provide their own copy method:

>>> arr2  = arr.copy()
>>> arr
array([10, 11, 12, 13, 14])
>>> arr2 += 100
>>> arr2
array([110, 111, 112, 113, 114])
>>>  arr
array([10, 11, 12, 13, 14]) 

这篇关于Python属性和numpy数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆