添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如果你的機器人功能多到一個程度,把全部的程式碼全部塞在一個文件裡顯然不是好辦法。
不但看起來雜亂,也難以維護,就算只是其中一個功能出問題也必須要把整個bot關掉。
這時候就可以使用 Cogs 的架構來寫,
可以將commands和listener等東西分堆塞在各自文件裡並方便我們裝卸。

官方文件 的說法,比較重要的有這幾點:

每個cogs都是 commands.Cog 的子類別

每個command要前加 @commands.command()

每個listener要前加 @commands.Cog.listener()

Cogs可以用 Bot.add_cog() 來註冊

Cogs可以用 Bot.remove_cog() 來卸載

通常會跟 Extension 功能配合

當然單純這樣條列出來是看不懂的,底下來看實例。
其檔案架構通常會長下面這樣
cogs資料夾是拿來放各個cogs的
core資料夾是拿來放一些你cogs可能會常用到的函數。
main.py是拿來運行的檔案,裡面也包含了載入和裝卸cogs的程式碼,會長的類似下面這樣:

from discord.ext import commands
import os
bot = commands.Bot('prefix')
#下面這塊從cogs資料夾中取出所有.py結尾的檔案並用load_extension載入cogs
for filename in os.listdir('./cogs'):
	if filename.endswith('.py'):
		bot.load_extension(f'cogs.{filename[:-3]}') 
@bot.event
async def on_ready():
	print('Test begin...') 
#這裡建個指令讓你可以載入Cog
@bot.command()
async def load(ctx, cog_name):
		bot.load_extension(f'cogs.{cog_name}')
	except:
		await ctx.send('Failed.')
		return
	await ctx.send('load success!')
#這裡建個指令讓你可以卸載Cog
@bot.command()
async def unload(ctx, cog_name):
		bot.unload_extension(f'cogs.{cog_name}')
	except:
		await ctx.send('Failed.')
		return
	await ctx.send('unload success!')
#這裡建個指令讓你可以重新載入Cog
@bot.command()
async def reload(ctx, cog_name):
		bot.reload_extension(f'cogs.{cog_name}')
	except:
		await ctx.send('Failed.')
		return
	await ctx.send('reload success!')
if __name__ == "__main__":
	bot.run('TOKEN')

接著在core底下加一個文檔,這裡我叫他init.py

import discord
from discord.ext import commands
class Cog_Extension(commands.Cog):
	def __init__(self, bot):
		self.bot = bot

接著來把一個指令用成cogs。
就拿前天那個请不要随意地触碰我! 十分感谢!來舉例
他原本的程式區塊大概長這樣:

@bot.command(aliases=['touch'])
async def t(message):
	await message.channel.send('请不要随意地触碰我! 十分感谢!')

把他用成cogs的話會需要把它塞進Class並加上我們剛剛寫的東西,所以會長得像這樣

from discord.ext import commands
from core.init import Cog_Extension
class touch(Cog_Extension):        #建議class名稱跟檔案名稱一樣
@commands.command(aliases=['touch'])    
	async def t(self, message):    #記得在參數列最前面加上self
		await message.channel.send('请不要随意地触碰我! 十分感谢!')

記得要import需要的套件

接著在下面加上setup的函數

from discord.ext import commands
from core.init import Cog_Extension
class touch(Cog_Extension):
	@commands.command(aliases=['touch'])
	async def t(self, message):
		await message.channel.send('请不要随意地触碰我! 十分感谢!')
def setup(bot):
	bot.add_cog(touch(bot))
#這裡的bot.add_cog(touch(bot))中的(bot)前面填上你class的名子

這樣運行後給機器人預設的help指令後就能看到結構了。

像這邊unload掉touch後可以發現輸t他也沒反應了,輸help也看不見了。

而load回來的話可以發現指令有反應了,help中也看的到了。

前述的的程式結構較簡單可能沒什麼感覺,但要是程式複雜到如下圖能夠先unload一塊調整完後再load回去還是挺方便的。