Is it possible to set a prefix for each cog?
For example the Cog with admin commands has the prefix pa! and the cog for some fun commands pf!.
Without using on_message.
Edit:
I guess I have to go more in detail:

My cog for serverstats has a command called 'stats', this command should get
triggered when I'm using pa!
My cog for fun has a 'stats' command too. This should be triggered when I'm
using pf!

My only thought up to now was to set the default prefix to p! and then call the command astats. But I want to have a better way.
I think this is an interesting question as I have had the same one for some time. I had an idea for implementing this myself although it does use the on_message function but not just that.
Basically my thought was to override the cog class and add a way for it to denote what prefix it should have. I thought use a custom argument in @commands.command to signify what prefix to use but this was for commands themselves.
Then in the on_message function you will need to determine there what command to call. Possibly the use of a global dict that correlates what prefix to what command.
This was just my own personal brainstorming and you will need to keep in mind if you allow each server to set their own prefixes and how to go about allowing that plus allowing them to set custom prefixes for each command. Good luck I hope this helps
Different prefix for each Cog?