这是创建 numpy 数组的只读视图的正确方法吗?

kMa*_*ter 10 python numpy python-3.x

我想创建对 NumPy 数组的只读引用。这是对(任何 NumPy 数组)进行b只读引用的正确方法吗?aa

def get_readonly_view(a):
    b = a.view()
    b.flags.writeable = False
    return b
Run Code Online (Sandbox Code Playgroud)

具体来说,我想确保上述内容不会“复制” 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)
Run Code Online (Sandbox Code Playgroud)

但客户端可以更改以下内容_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]]
Run Code Online (Sandbox Code Playgroud)

虽然我想baz.a[1, 2] = 10提出一个例外。

nor*_*ok2 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
Run Code Online (Sandbox Code Playgroud)