如何修复Discord机器人代码中的AttributeError: 'NoneType' object has no attribute 'get'错误
on_message Event Let's break down what's going wrong here and fix your bot step by step—starting with that annoying AttributeError: 'NoneType' object has no attribute 'get' error.
Root Cause & Key Fixes
1. Initialize self.check_buttons (and self.btns)
The main error happens because self.check_buttons isn't initialized as a dictionary. Right now it's None, so calling .get() on it throws that error. Add these lines to your bot class's __init__ method to set up these attributes properly:
def __init__(self): # ... your existing setup code (like initializing self.client) self.check_buttons = {} # Empty dict to track user button states self.btns = [] # Initialize with your actual button options if you have them
2. Fix Discord.py's Message Sending Syntax
Discord.py deprecated send_message ages ago, and all API calls are async—so you must use await. Also, sending DMs to users is done directly via the user object, not self.channel (unless you're sending to a server channel). Update your message-sending lines like this:
- Replace
self.channel.send_message(message.author.id, ans)withawait message.author.send(ans) - Replace
self.send_message(message.author.id, msg)withawait message.author.send(msg) - Replace
self.channel.send_message(message.author.id, message.content)withawait message.author.send(message.content)(if you meant to log to a server channel, useawait self.channel.send(f"User {message.author.id}: {message.content}")instead)
3. Clean Up Redundant Code
You're calling self.check_buttons.get(...) multiple times—simplify this by fetching the value once at the start of the check:
user_buttons = self.check_buttons.get(message.author.id, None) if user_buttons: # Rest of your logic using user_buttons instead of repeated get() calls
4. Don't Forget await Everywhere
Your on_message function is async, so every Discord API call (like sending messages) needs the await keyword. You missed this in all your message-sending lines, which would cause errors even after fixing the AttributeError.
Full Fixed Code
@self.client.event async def on_message(message): # Ignore messages sent by the bot itself if message.author == self.client.user: return # Get the user's active button list (if it exists) user_buttons = self.check_buttons.get(message.author.id, None) if user_buttons: ans = None # Loop through buttons to find a match with the user's input for idx, btn in enumerate(user_buttons): if message.content.lower() == btn.lower() or message.content.lower() == f"#{idx + 1}": ans = btn break if ans: # Send the matched answer to the user await message.author.send(ans) # Clear the user's button entry (remove instead of keeping empty list) del self.check_buttons[message.author.id] else: # Build error message with valid button options msg = "You entered an invalid value. Copy (Short command: # and numbers buttons):\n" for idx, btn in enumerate(self.btns): msg += f"{idx + 1}. {btn}\n" await message.author.send(msg) else: # Echo the user's message back via DM await message.author.send(message.content) # Log user ID + message to your target channel (ensure self.channel is initialized!) if self.channel: await self.channel.send(f"User {message.author.id}: {message.content}")
Extra Tips
- Make sure
self.channelis properly set to a valid Discord channel object in your class's__init__—if it'sNone, that logging line will throw another error. - Using
enumerate()instead ofrange(len(...))makes your loops cleaner and easier to read.
内容的提问来源于stack exchange,提问作者Four_di

