Python 3.6.4中async代码出现AttributeError: __aexit__错误求助
AttributeError: __aexit__ in Python 3.6.4 Hey there! Let's break down this AttributeError: __aexit__ issue you're facing—this error almost always boils down to mixing up synchronous and asynchronous context managers, which is super easy to do by accident. Here's what's going on and how to fix it:
Common Causes & Solutions
1. You're using an async context manager with a regular with statement
Async context managers (think tools for async I/O like async database connections or HTTP clients) define __aenter__ and __aexit__—async methods—instead of the standard __enter__/__exit__ used by regular context managers. If you try to slap one into a normal with block, Python will look for the synchronous __exit__ method and throw this error when it can't find it.
Example of the mistake:
class AsyncDatabaseConnection: async def __aenter__(self): # Async setup logic here return self async def __aexit__(self, exc_type, exc_val, exc_tb): # Async cleanup logic here pass # Wrong! Using async context manager with regular with with AsyncDatabaseConnection(): # Do stuff pass
The fix:
Use async with instead, and make sure you're running this inside an async function. Since you're on Python 3.6 (which doesn't have asyncio.run() yet), you'll need to use the event loop directly:
import asyncio async def main(): async with AsyncDatabaseConnection(): # Do your async work here print("Connected to database asynchronously") # Run the async function loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
2. You messed up a custom synchronous context manager
If you wrote your own context manager for synchronous code, double-check that you defined the right methods. If you accidentally used __aexit__ (the async version) instead of __exit__, or forgot to define __exit__ entirely, Python will throw this error.
Example of the mistake:
class SyncFileHandler: def __enter__(self): self.file = open("example.txt", "r") return self.file # Oops! Used __aexit__ instead of __exit__ async def __aexit__(self, exc_type, exc_val, exc_tb): self.file.close()
The fix:
Replace the async __aexit__ with a synchronous __exit__ method:
class SyncFileHandler: def __enter__(self): self.file = open("example.txt", "r") return self.file # Correct synchronous __exit__ method def __exit__(self, exc_type, exc_val, exc_tb): self.file.close()
3. Third-party library compatibility issues
Some older libraries might have async context managers that aren't fully compatible with Python 3.6.4, or might have bugs in their context manager implementations. If the error comes from a library you're using:
- Check the library's documentation to confirm it supports Python 3.6
- Try updating the library to the latest version that supports 3.6
- Verify you're using the library's context manager correctly (e.g., using
async withif it's meant to be async)
Quick Troubleshooting Steps
- Scan your code for all
withstatements—look for any that use objects from async libraries (likeaiohttp,asyncpg, etc.) - Check the source code or docs for the context manager to see if it's async (look for
__aenter__/__aexit__methods) - If it's async, switch to
async withand wrap the code in an async function run via the event loop
内容的提问来源于stack exchange,提问作者Bjorn Mistiaen

