I ran into the following problem :
First_File:
import discord
import second_file
client = discord.Client()
[...]
@client.event
async def on_message(message):
if message.content.lower().startswith("!hi"):
await second_file.hello()
Second_File:
from first_file import client
from first_file import on_message
async def hello(client, on_message):
await client.send_message(message.channel, "Hiii <3!")
And now I get the error message: module 'second_file' has no attribute 'hello'.
Why won't it call the function?
This is quite a cryptic error message compared to what's actually happening. You're attempting to import from both files at the same time and that causes issues. Whenever you import, the complete file will be interpreted, even though you're using
from file import thing. To be more specific to your case,await second_file.hello()fails becausesecond_filehasn't been fully imported yet when you get to it.Here's what's being executed and why it fails (you can verify this from the stack trace that you get when you try to import the file in a python3 REPL):
import second_filein first_file, stops interpretation of first_file and triggers a complete interpretation of second_file.from first_file import clientstops interpretation of second_file and triggers a complete interpretation of first_file.import second_fileis skipped (otherwise you'd get an infinite loop). Continue interpreting first_file until...await second_file.hello(): ignoring the syntax error wherehello()accepts two arguments, notice the interpreter doesn't know abouthello()yet. Obviously, this is a syntax error since you're using something you haven't defined yet!To fix this, use the architecture you've already created. Just drop the two import statements at the start of second_file. I've also taken the liberty of adding the
messageargument it seems you forgot. Not sure why you even need theon_messagefunction to be passed in, but to be fair I don't know your use case.first_file
second_file