【问题标题】:How to use discord.py asynchronously with another function如何将 discord.py 与另一个函数异步使用
【发布时间】:2022-06-21 05:59:18
【问题描述】:

我正在尝试以在启动时运行函数 background() 同时运行 client.run() 来启动不和谐机器人的方式运行此代码。我怎样才能做到这一点?在其当前状态下,根据我调用上述函数的顺序,它只运行第一个,所以在这种情况下它只运行不和谐机器人,因为我首先调用了函数......

from hashlib import new
from re import I
from web3 import Web3
import sys, json, time, asyncio, threading
from logging import exception
import json
import time
import urllib3
import discord
from discord.ext.commands import Bot
from discord.ext import commands

# set rpc
web3 = Web3(Web3.HTTPProvider("rpc goes here (i have hidden for this post)"))

# use https://github.com/Cog-Creators/Red-DiscordBot/issues/581 to solve SSL problems on Mac OS
# use "token" not "client secret" for discord bot
discord_token = ('discord secret here i have hidden for this post')
# init discord stuff
client = discord.Client()
# set bot command prefix
client = commands.Bot(command_prefix = '$') #put your own prefix here


# take block data input, parse for new contract, then call discord function to broadcast
async def contractTx(txhash):
    # call when new block is found to get contract addy and send it to discord
    new_contract = web3.eth.get_transaction_receipt(txhash)
    global contract_address
    contract_address = new_contract['contractAddress']
    print(f"New contract deployed: {contract_address}")
    await new_contract_discord(contract_address=contract_address)



# runs on program startup
async def background():
    # set block index
    global block_index
    block_index = web3.eth.get_block_number()
    # start looping through blocks
    while True:
        if block_index != web3.eth.get_block_number():
            # new block, do the things
            # set current block to new block
            block_index = web3.eth.get_block_number()
            # check if transactions in new block contain new contract creation
            # if yes, send to main function
            print(f"NEW BLOCK: {block_index}")
            global transactions
            current_block = web3.eth.get_block(block_index, full_transactions=True)
            transactions = current_block.transactions
            for tx in transactions:
                if tx['to'] != None:
                    # is a contract creation tx, send to export function
                    task1 = asyncio.create_task(contractTx(tx['hash'].hex()))
        else:
            # still the same block, so wait a bit
            print("no new blocks")
            await asyncio.sleep(1)



@client.event
async def on_ready():
    print("bot online") #will print "bot online" in the console when the bot is online

@client.event
async def new_contract_discord(ctx, contract_address):
    channel = client.get_channel(949889447938367531)
    await channel.send(f"new contract: {contract_address}")


# test command so you know how it works
# do $foo "string" and it responds with "string"
@client.command()
async def foo(ctx, arg):
    await ctx.send(arg)

# run the discord bot with the token
client.run(discord_token)

# run the background func
asyncio.run(background())```

【问题讨论】:

  • asyncio 有一些方法可以在开始循环之前将许多函数添加到队列中,这将同时执行它们。尝试create_task 用于第一个功能,然后尝试run() 用于第二个功能
  • @furas 我做了discordtask = asyncio.create_task(client.run(discord_token)) asyncio.run(background()) 仍然只有第一个函数运行,第二个没有
  • 只有create_task(discord_token()) 没有run()。您也可以尝试不同的顺序 - create_task(background())client.run(discord_token)
  • 其他想法(但未经测试):使用@tasks.loop(count=1)def background() 在启动discord 后启动它 - doc discord.ext.tasks – asyncio.Task helpers。其他想法:在on_ready() 中运行await background() 并可能在while True 的每个循环中使用asyncio.sleep(0.1) - 这样它可能会转到其他功能。
  • 嘿,我也遇到了同样的问题,在这里通过简单的 url 请求查看解决方案,您可以在代码中的任何位置发送消息:stackoverflow.com/questions/62203617/…

标签: python asynchronous discord.py web3py


【解决方案1】:
import threading
def A():
    while True:
        print("A")
def B():
    while True:
        print("B")
threading.Thread(target=A).start()
threading.Thread(target=B).start()

这将输出 ABABAB... 所以,函数是同时运行的。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
  • @xDev120 我收到一个错误:set_wakeup_fd only works in main thread of the main interpreter During handling of the above exception, another exception occurred:
  • @JohnWarts 看起来你的函数想在主线程上运行。您应该看到异步 (docs.python.org/3/library/asyncio.html) 和线程 (docs.python.org/3/library/threading.html) 文档。
猜你喜欢
  • 2021-10-21
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 2020-09-18
  • 1970-01-01
相关资源
最近更新 更多