AttributeError:在with语句内使用numpy nditer时,会出现__enter__

时间:2018-09-02 17:39:50

标签: python arrays numpy scipy iteration

我试图遍历一个numpy数组并更改其中的一些值。这是我的代码,实际上是从文档(numpy nditer docs)中复制的:

import numpy as np

a = np.arange(6).reshape(2,3)
print(a)
with np.nditer(a, op_flags=['readwrite']) as it:
  for x in it:
    x[...] = 2 * x

print(a)

但我不断得到以下追溯:

Traceback (most recent call last):
  File "text.py", line 5, in <module>
    with np.nditer(a, op_flags=['readwrite']) as it:
AttributeError: __enter__

我做错了什么吗?文档中是否有错误(nditerwith的使用已被弃用)?

1 个答案:

答案 0 :(得分:2)

您正在查看Numpy 1.15的文档,该文档使用new feature of nditer() introduced in that release

  

在某些条件下,必须在上下文管理器中使用nditer

     

在带有numpy.nditer"writeonly"标志的"readwrite"上使用时,在某些情况下nditer实际上并不能为您提供可写数组的视图。相反,它会为您提供一个副本,并且如果您对副本进行更改,nditer随后会将这些更改写回到您的实际数组中。当前,这种写回发生在对数组对象进行垃圾回收时,这使得该API在CPython上容易出错,而在PyPy上则完全损坏。因此,nditer现在每当与可写数组(例如with np.nditer(...) as it: ...)一起使用时,都应该用作上下文管理器。对于上下文管理器不可用的情况(例如在生成器表达式中),您也可以显式调用it.close()

该错误表明您具有Numpy的早期版本; with语句仅适用于*上下文管理器,后者must implement __exit__ (and __enter__)AttributeError例外表示在您的Numpy版本中,所需的实现不存在。

要么升级,要么不使用with

for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2 * x

使用CPython时,可能仍然会遇到导致1.15版本中进行更改的问题。使用PyPy时,您遇到这些问题,升级是您唯一的选择。

您可能想参考1.14 version of the same documentation entry you used(或更具体地说,请确保参考pick the right documentation for your local version