我想创建一个对NumPy数组的只读引用。这是使b
成为对a
的只读引用的正确方法吗(a
是任何NumPy数组(?
def get_readonly_view(a):
b = a.view()
b.flags.writeable = False
return b
具体来说,我想确保以上内容不会"复制"a
的内容?(我试着用np.shares_memory
测试这个,它确实返回了True
。但我不确定这是否是一个正确的测试。(
此外,我想知道get_readonly_view
是否已经在NumPy中实现了?
更新有人建议将数组转换为类属性,使其只读。我认为这不起作用:
import numpy as np
class Foo:
def __init__(self):
self._a = np.arange(15).reshape((3, 5))
@property
def a(self):
return self._a
def bar(self):
print(self._a)
但客户端可以更改_a
:的内容
>> baz = Foo()
>> baz.bar()
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
>> baz.a[1, 2] = 10
>> baz.bar()
[[ 0 1 2 3 4]
[ 5 6 10 8 9]
[10 11 12 13 14]]
而我希望CCD_ 9引发一个异常。
您的方法似乎是创建只读视图的建议方法。
特别地,arr.view()
(也可以写为切片arr[:]
(将创建对arr
的引用,而修改writeable
标志是使NumPy数组只读的建议方式。
该文档还提供了一些关于writeable
属性继承的附加信息:
可以写入数据区域。将其设置为False会锁定数据,使其只读。视图(切片等(在创建时从其基数组继承WRITEABLE,但在基数组保持可写时,可写数组的视图随后可能被锁定。(事实并非如此,因为锁定数组的视图可能不可写。但是,目前,锁定基对象不会锁定任何已经引用它的视图,因此在这种情况下,可以通过以前创建的可写视图更改锁定数组的内容。(试图更改不可写数组会引发RuntimeError异常。
只是重申并检查正在发生的事情:
import numpy as np
def get_readonly_view(arr):
result = arr.view()
result.flags.writeable = False
return result
a = np.zeros((2, 2))
b = get_readonly_view(a)
print(a.flags)
# C_CONTIGUOUS : True
# F_CONTIGUOUS : False
# OWNDATA : True
# WRITEABLE : True
# ALIGNED : True
# WRITEBACKIFCOPY : False
# UPDATEIFCOPY : False
print(b.flags)
# C_CONTIGUOUS : True
# F_CONTIGUOUS : False
# OWNDATA : False
# WRITEABLE : False
# ALIGNED : True
# WRITEBACKIFCOPY : False
# UPDATEIFCOPY : False
print(a.base)
# None
print(b.base)
# [[0. 0.]
# [0. 0.]]
a[1, 1] = 1.0
# ...works
b[0, 0] = 1.0
# raises ValueError: assignment destination is read-only