미사용/(舊)디스코드봇 강좌

디스코드봇(파이썬) 05 | 메세지의 특정부분만 읽어보자.

건유1019 2020. 4. 11. 12:00

이번 강좌에서는 슬라이스와 split를 사용해서 특정 부분만 읽어보려고 합니다. 

slice와 split은, "[접두어](명령어) (이후 받을 내용~~~)" 이렇게 이후로 받을 메시지가 있을 경우 사용하게 됩니다.

 

따라서 if문 또한 "=="로 일치할 때 사용하는 것보다, 아래처럼 사용하게 됩니다.

if message.content.startswith("!ping"):

이제부터 이 두 가지를 활용한 특정 부분을 읽어봅시다.


slice를 사용하여 특정 부분을 읽어보자.

 

slice는 사실상 파이썬의 기본 기능 중 하나로, 파이썬을 여시고 현재 작성 중인 디스코드 봇 코드는 나중에 수정하고, 파이썬 쉘을 사용해서 테스트해봅시다.

msg = "메세지 내용|1234567890|아무내용(장문)"
print(msg[6:]) # |1234567890|아무내용(장문) 라고 출력
print(msg[0:6]) # 메세지 내용 라고 출력

이렇게 하시면, "|1234567890|아무 내용(장문)"라고 출력됩니다. slice는 파이썬 배열 사용법과 매우 비슷하며

msg["시작값":"끝값"]으로 설정해주실 수 있습니다.

 

또한, 저 상태에서 아래의 내용을 입력해주시면 다음과 같이 출력됩니다.

print(msg[0])

이렇게 입력하시면 "메"라는 저 msg 변수의 첫 번째 글씨가 나올 겁니다. 여기서 slice는 0부터 시작됩니다.

 

따라서 한 글자를 읽고 싶으면 msg["글자 순번"]을 적으시면 됩니다.

만약에 "안녕하세요." 기준에서 슬라이스를 사용하게 된다면 아래의 표처럼 저장하게 됩니다.

0번째 1번째 2번째 3번째 4번째 5번째
.

이제 이것을 응용하여, 디스코드 봇이 따라 하게 만들어 봅시다.

import discord
import asyncio
 
client = discord.Client()
 
@client.event
async def on_ready(): 
    print("디스코드 봇 로그인이 완료되었습니다.")
    print("디스코드봇 이름:" + client.user.name)
    print("디스코드봇 ID:" + str(client.user.id))
    print("디스코드봇 버전:" + str(discord.__version__))
    print('------')
    await client.change_presence(status=discord.Status.online, activity=discord.Game("서술"))
 
@client.event
async def on_message(message): 
    if message.content.startswith("!따라하기"):
    	answer = message.content[6:]
        await message.channel.send(answer) 
 
client.run('토큰번호')

위 와같이 코드를 작성해주시고 on_ready 에선 지난 2편에서 진행하였으니 요약하고 on_message 부분만 해석하도록 하겠습니다.

@client.event
async def on_message(message): 
    if message.content.startswith("!따라하기"):
    	answer = message.content[6:]
        await message.channel.send(answer)

메시지 내용에 "!따라하기"라고 시작한다면 if문이 작동하게 됩니다.

answer라는 변수 안에 message.content[6:] 라는 슬라이스를 사용한 메시지 내용을 읽습니다.

그리고 await message.channel.send를 통해 그 내용을 따라 하게 만듭니다.


split를 사용하여 특정 부분을 읽어보자.


이제 split을 사용하여, 특정 부분을 읽어보겠습니다. 일단 이것 또한 디스코드 기본 기능이 아닌 파이썬 문자열 기능이기 때문이기에 shell에서 먼저 테스트해봅시다.

msg = "아무내용 아무말씀 아무디스코드"
msg_l = msg.split()

일단 msg 변수 안에 "아무내용 아무말씀 아무디스코드"라는 내용을 넣어준 뒤 split을 사용해줍니다.

split은 특정 문자를 기준으로 리스트를 만드는 것입니다. 오히려 자바스크립트랑 여러 언어에 존재했던 거 같은 이 기능 때문인지 slice보다 split을 더 많이 쓰게 됩니다.

print(msg_l)

이렇게 하시면 ['아무내용', '아무말씀', '아무디스코드'] 라고 출력될 것입니다. 즉, 리스트로 저장된다는 겁니다.

0번째 1번째 2번째
아무내용  아무말씀  아무디스코드

위와 같이 0번부터 순서대로 리스트에 들어가게 됩니다.

print(msg_l[1])

이렇게 하면 "아무말씀"이라는 단어가 출력될 것입니다. 그러나 배열의 경우 지정된 인자보다 더 많이 쓰게 되면 오류가 발생되게 됩니다. 지금은 3(0~2) 개의 인자가 존재하지만, 여기서 4번째 인자를 불러오라고 하면 오류가 발생합니다.

Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    print(msg_l[4])
IndexError: list index out of range

아래의 내용처럼 인덱스 에러가 발생할 수 있으니, 조심하시기 바랍니다. 이제 저는 이것을 디스코드봇에 응용해서 특정 내용을 불러올 것입니다.

import discord
import asyncio
 
client = discord.Client()
 
@client.event
async def on_ready(): 
    print("디스코드 봇 로그인이 완료되었습니다.")
    print("디스코드봇 이름:" + client.user.name)
    print("디스코드봇 ID:" + str(client.user.id))
    print("디스코드봇 버전:" + str(discord.__version__))
    print('------')
    await client.change_presence(status=discord.Status.online, activity=discord.Game("서술"))
 
@client.event
async def on_message(message): 
  if message.content.startswith("!테스트"):
      msg_l = message.content.split()
      try:
          data = msg_l[1]
      except:
          await message.channel.send("내용을 입력해주세요!")
          return
      await message.channel.send(data)
 
client.run('토큰번호')

이렇게 하고 분석을 해봅시다. 아까 위에처럼 on_ready 까지는 같은 내용이니 생략하고 on_message 부분만 해석해보겠습니다.

if message.content.startswith("!테스트"):
	msg_l = message.content.split()
	try:
		data = msg_l[1]
	except:
		await message.channel.send("내용을 입력해주세요!")
		return
	await message.channel.send(data)

msg_l이라는 변수에 split을 하여, 리스트 값을 넣어줍니다.

msg_l[1]을 data라는 변수에 넣어주고, await message.channel.send를 통해 보내줍니다. 그러나 아까 설명했듯이 만약에 작성하지 않으면 그 값이 존재하지 않으므로 에러가 발생합니다 따라서, try과 except를 통하여 예외처리를 해주었습니다. 또한 excpet에서 예외처리가 발생하는 경우 내용을 입력해 달라고 요청합니다.

 

이것을 실행하면? 이상한 점을 찾으실 겁니다. "!테스트 안녕하세요. 개발자라고 합니다."라고 작성 시에 "안녕하세요."라는 값만 돌아옵니다 왜일까요? 바로 list에 첫 번째 값만 불러왔기 때문입니다. 리스트는 특성상 여러 개를 불러올 수가 없습니다. 아까처럼 [시작값:끝값] 이것을 사용해도, 리스트로 돌아오기 때문에 불가능합니다.

 

그리고 split은 split("\") 등의 " " 이 기준에서만 리스트로 저장하는 것이 아닌 다른 단어로도 리스트를 저장해 주실수 있습니다.


알아두면 좋은 것!

 

이제 저 두 개(split, slice)를 사용할 때, 알아두면 좋은 한 개를 더 알아보겠습니다. 아까처럼 파이썬 쉘을 열어주시고 아래의 내용을 입력해주세요.

msg = "안녕하세요. 개발자라고 합니다."
msg_l = msg.split()

print(len(msg))
print(len(msg_l))

이렇게 될 경우 17과 3의 값이 돌아오게 됩니다. len 경우에는 "글씨 길이" 혹은 "리스트 개수"를 셀 때 사용되며 split() 이므로 " " 기준에서, 리스트가 분리된 거기 때문에 "안녕하세요.","개발자라고","합니다." 이렇게 3개가 있으므로, 3이라는 값이 출력되며 위에 17은 저 글씨를 모두 세면 17개이기 때문에 17이라고 출력됩니다.


이상으로 5편을 마칩니다. 오늘은 분량이 길지 않는것 같네요. 다음강의를 위해(?) 오늘은 슬라이스와 split에 대해 알아보았습니다. 다음에는 디스코드 함수 목록과 디스코드 봇으로 상호작용하는 것에 대해 강의를 진행해보겠습니다.