Discord.py komuta birden fazla değişken ekleme

Shankusu

Decapat
Katılım
5 Şubat 2022
Mesajlar
221
Daha fazla  
Cinsiyet
Erkek
Merhabalar, bir zamanlayıcı bot yapmak istiyorum. Bu botta 3 tane süre belirtmem ve 3 süreyi de arka arkaya sayması gerek. Lakin komuta 2. ve 3.'ü değişkenleri ekleyemedim.

Python:
import discord
from discord.ext import commands, tasks
import asyncio

# Botun prefixi

bot = commands.Bot(command_prefix="!", intents = discord.Intents.all())



# Bot komutları
@bot.event
async def on_ready():
    print(f'Bot {bot.user} olarak giriş yaptı!')

@bot.command(name='timer')
async def timer(ctx, ceviri: int):
    """
    Kullanıcıya bir zamanlayıcı başlatır.
    Usage: !timer <süre(saniye)>
    """
    if ceviri <= 0:
        await ctx.send("Şebeke yok")
    else:
        await start_timer(ctx, ceviri)

async def start_timer(ctx, ceviri):
    await ctx.send(f"Çeviri sayacı başlatıldı! {ceviri} saniye boyunca geri sayılıyor...")
   
    # Geri sayım
    await asyncio.sleep(ceviri)

    await ctx.send(f"Çeviri bitti! {ceviri} saniye geçti.")
 
Son düzenleyen: Moderatör:
Python:
import discord
from discord.ext import commands, tasks
import asyncio

# Botun prefixi

bot = commands.Bot(command_prefix="!", intents = discord.Intents.all())



# Bot komutları
@bot.event
async def on_ready():
    print(f'Bot {bot.user} olarak giriş yaptı!')

@bot.command(name='timer')
async def timer(ctx, ceviri: int):
    """
    Kullanıcıya bir zamanlayıcı başlatır.
    Usage: !timer <süre(saniye)>
    """
    if ceviri <= 0:
        await ctx.send("Şebeke yok")
    else:
        await ctx.send(f"Çeviri sayacı başlatıldı! {ceviri} saniye boyunca geri sayılıyor...")
           await ceviri_sonuc = asyncio.sleep(ceviri, result=f"Çeviri bitti! {ceviri} saniye geçti.")
        await ctx.send(ceviri_sonuc)

Birincisi, timer ve start_timer diye cok gereksiz bir sekilde ikiye bolmussunuz. Verdigim koddaki gibi, start_timer'i timer'a gayet basit bir sekilde ekleyip calistirabilirdiniz, hem daha etkili olurdu.

Ikincisi ise gorunuse gore asyncio kutuphanesini yeterince iyi arastirmamissiniz. asyncio.sleep(<saniye_biriminde_sure>, result=<belirtilen_sure_boyunca_beklenildikten_sonra_cikacak_sonuc>)bu sekilde de kullanabilirsiniz. result= degerini girdikten sonra bu bekleme islemini bir degiskenin icine koyup ister mesaj olarak sunucuya atin isterseniz de kod terminaline yazdirin, tamamen size kalmis bir sey bu. Zaten kodun da gayet acik oldugunu dusunuyorum o yuzden fazla anlatmaya gerek yok gibi. Tam anlayamadiginiz, sormak istediginiz yerler varsa soyleyin lutfen.
 
Dokümandan öğrendiğim kadarıyla komutlar birden fazla argümanı destekliyor. Tam olarak 3 tane süre belirtmek isterseniz:

Python:
@bot.command(name="timer")
async def timer(ctx, ceviri1: int, ceviri2: int, ceviri3: int):
    """
    Kullanıcıya üç zamanlayıcı başlatır.
    Usage: !timer <süre1(saniye)> <süre2(saniye)> <süre3(saniye)>
    """
    for ceviri in [ceviri1, ceviri2, ceviri3]:
        if ceviri <= 0:
            await ctx.send("Şebeke yok")
        else:
            await start_timer(ctx, ceviri)

Değişken sayıda argümanı destekletmek de mümkünmüş, yine dokümanda gösterilmiş:

Python:
@bot.command(name="timer")
async def timer(ctx, *ceviriler: int):
    """
    Kullanıcıya istenen sayıda zamanlayıcı başlatır.
    Usage: !timer <süre1(saniye)> <süre2(saniye)> ... <süreN(saniye)>
    """
    for ceviri in ceviriler:
        if ceviri <= 0:
            await ctx.send("Şebeke yok")
        else:
            await start_timer(ctx, ceviri)

Burada ceviriler, önündeki * sayesinde komuta (fonksiyona) kaç argüman verildiyse (ctx dışında) onların hepsini tutan bir liste (tuple). Bu sayede içindeki argümanları döngüyle gezebiliyoruz.

Zamanlayıcıların paralel olarak çalışmasını isterseniz (Aynı anda çalışmaya başlayacaklar, birbirlerini beklemeyecekler.) asyncio kütüphanesinin create_task metodunu kullanabilirsiniz:

Python:
@bot.command(name="timer")
async def timer(ctx, *ceviriler: int):
    """
    Kullanıcıya istenen sayıda zamanlayıcı başlatır.
    Usage: !timer <süre1(saniye)> <süre2(saniye)> ... <süreN(saniye)>
    """
    for ceviri in ceviriler:
        if ceviri <= 0:
            await ctx.send("Şebeke yok")
        else:
            asyncio.create_task(start_timer(ctx, ceviri))
            # await start_timer(ctx, ceviri)

Burada iş, teoride süresi en fazla olan zamanlayıcının süresi bittiğinde bitecek.



asyncio.sleep(<saniye_biriminde_sure>, result=<belirtilen_sure_boyunca_beklenildikten_sonra_cikacak_sonuc>)bu sekilde de kullanabilirsiniz.

Teşekkür ederim bilgi için, bilmiyordum.

Birincisi, timer ve start_timer diye cok gereksiz bir sekilde ikiye bolmussunuz. Verdigim koddaki gibi, start_timer'i timer'a gayet basit bir sekilde ekleyip calistirabilirdiniz, hem daha etkili olurdu.

Zamanlayıcı başlatma işinin ayrı bir metot olarak yazılıp kullanılması faydalı olmuş aslında. Anlaşılırlığı artırmış ve tahminimce performansa büyük bir etkisi yoktur. Hem sonradan bu metoda yeni yeni şeyler eklenirse veya başka bir komutta kullanılırsa ayrı bir metot olarak yazılmış olmasının faydası artacaktır.
 
Zamanlayıcı başlatma işinin ayrı bir metot olarak yazılıp kullanılması faydalı olmuş aslında. Anlaşılırlığı artırmış ve tahminimce performansa büyük bir etkisi yoktur. Hem sonradan bu metoda yeni yeni şeyler eklenirse veya başka bir komutta kullanılırsa ayrı bir metot olarak yazılmış olmasının faydası artacaktır.
Dogru diyorsunuz. Su aralar kodu kisaltmaya kafayi taktim desem yeridir. Sanirim dediginiz gibi, ayri bir metot olarak yazilmasi daha kullanisli olur. Bu sekilde kodu esnek tutmanin performansa oyle aman aman bir etki edecegini ben de dusunmuyorum.
 
Geri
Yukarı