首页 > 解决方案 > AttributeError: __enter__ 在 with 语句中使用 numpy nditer 时

问题描述

我正在尝试遍历一个 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__

我做错了什么,还是文档中有错误(不推荐使用nditerinside with)?

标签: pythonarraysnumpyscipyiteration

解决方案


您正在查看 Numpy 1.15 的文档,这使用了该版本中引入的新功能nditer()

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

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

该错误表明您使用的是早期版本的 Numpy;该with语句仅适用于必须实现(and )的上下文管理器,并且异常表明在您的 Numpy 版本中不存在所需的实现。__exit____enter__AttributeError

要么升级,要么不使用with

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

但是,在使用 CPython 时,您可能仍然会遇到导致 1.15 版本中所做更改的问题。在使用 PyPy 时,您遇到这些问题,而升级是您唯一适当的办法。

您可能希望参考您使用的同一文档条目的 1.14 版本(或者更具体地说,确保为您的本地版本选择正确的文档


推荐阅读