Python错误:"AttributeError: __enter__"

12

所以,我无法加载我的 JSON 文件,也不知道原因,有人可以解释一下我做错了什么吗?

async def give(msg, arg):
    if arg[0] == prefix + "dailycase":
                with open("commands/databases/cases.json", "r") as d:
                     data = json.load(d)

由于某些原因,我得到了这个错误:

    with open("commands/databases/cases.json", "r") as d:
AttributeError: __enter__

6
你的代码中是否将内置的 open 重定义为其他内容?无论是通过赋值(open =)还是从其他地方导入它(from place import open)都可能会出现这种情况。 - Lukas Graf
这不完全是一个副本,但是相关:https://dev59.com/7nI-5IYBdhLWcg3wKVE9 - Green Cloak Guy
为了测试@LukasGraf的理论:print(open.__doc__)...如果您看不到一个以“打开文件并返回流”开头的内部Python文本的大块,则他的理论是正确的。 - JacobIRR
2
@JacobIRR:您可以通过执行“import io”并测试“open is io.open”来确认是否为内置的“open”(在Python 3中,内置的“open”别名为“io.open”)。 - ShadowRanger
@RyanHaining:不一定;直到问题项完全构建,才会查找__enter__;很有可能open调用成功了,只是引用了错误的open,但一旦成功,那个错误的open就不再调用堆栈上了。 - ShadowRanger
@ShadowRanger 你说得对。我没有意识到,已经删除了评论。 - Ryan Haining
4个回答

19
很可能是在您的代码中将Python的内置函数open重新分配给其他内容(几乎没有其他合理的解释方式可以解释此异常)。
然后,with语句将尝试将其用作上下文管理器,并在首次进入with块时尝试调用其__enter__方法。这导致您看到的错误消息,因为您的名为open的对象无论是什么,都没有__enter__方法。
在你的 Python 模块中查找重新赋值 `open` 的地方。最明显的是:
  • 全局范围内的函数,如 `def open(..)`
  • 直接使用 `open =` 进行重新赋值
  • 导入语句,如 `from foo import open` 或 `import something as open`
函数是最有可能的嫌疑人,因为它看起来你的 `open` 实际上是一个可调用对象。
为了帮助你找到意外绑定到 `open` 上的对象,你也可以尝试:
print('open is assigned to %r' % open)

with语句之前,如果它没有显示<built-in function open>,那么你就找到了罪魁祸首。


1
我仔细检查了所有文件的脚本,看看我做错了什么,但是没有任何名为“open”的变量或导入,但我犯了一个错误,我发现我创建了一个名为“open”的函数,而我没有意识到。感谢您的支持,对此我很抱歉! - Caio Alexandre
不用谢,很高兴能帮到你 - 遮蔽内置名称是一个常见的陷阱,曾经让我们大多数人都被绊倒过 ;-) - Lukas Graf
还要检查Python版本。OP的语法只支持3.8+。我的解决方案下面有Python 3.6的语法。 - Under-qualified NASA Intern
我在这个基础代码上也遇到了相同的错误,但不知道为什么。https://snippet.host/pbwp - Grimeire
1
@Grimeire requests.get 不是上下文管理器,因此您不能在 with 语句中使用它。但是 requests.Session() 是 - 这可能是您想要使用的。因此,您可以这样做 with requests.Session() as session: r = session.get(dl_link, stream=True, headers=headers) - Lukas Graf
我在评论后发现,当我在另一台机器上运行我提供的完全相同的代码时,它可以按照预期工作。我将研究你的代码并测试是否可以在两台机器上运行。谢谢。 - Grimeire

18

我在这一行代码中遇到了错误:

with concurrent.futures.ProcessPoolExecutor as executor:

缺少括号 是问题所在

with concurrent.futures.ProcessPoolExecutor() as executor:

0
在我的情况下,我有意地定义了一个名为 stopwatch 的自定义 with 函数。
with stopwatch('upload %d bytes' % len(data)):
    ...code...

所以必须添加:

import contextlib

并将自定义函数定义前缀如下:

@contextlib.contextmanager
def stopwatch(message):
    ...code...

-1
我的问题是我期望os.open像内置的open一样工作... 这会导致AttributeError: __enter__
import os 
with os.open('out.txt', os.CREAT) as f:
  f.write('hello world')

这不会

with open('out.txt', 'w') as f:
  f.write('hello world')

我想用from os import open很容易引起OP的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接