【问题标题】:ValueError: circular reference detected with replit databaseValueError:replit 数据库检测到循环引用
【发布时间】:2021-07-04 07:32:36
【问题描述】:

所以我正在为我的服务器开发带有 discord.py 的不和谐机器人。我正在使用replit的数据库系统。当我尝试将我的类Player 的实例添加到该数据库的键时,它会说:


Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 36, in jointothefun
    db[f"{context.message.author.id}"] = p
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 486, in __setitem__
    self.set(key, value)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 495, in set
    self.set_raw(key, _dumps(value))
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 56, in dumps
    return json.dumps(val, separators=(",", ":"), cls=DBJSONEncoder)
  File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
    return cls(
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
ValueError: Circular reference detected

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 902, in invoke
    await ctx.command.invoke(ctx)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 864, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ValueError: Circular reference detected

我不知道为什么它根本不起作用。有人可以帮忙吗?

哦,还有源代码(是的,我知道我正在制作意大利面条代码)

机器人的主文件

from discord.ext import commands
from replit import db
from alive import startup
from playerclass import Player
print(db.keys())
class PlayerClient(discord.Client):
    async def on_member_join(self,member):
        print(f"{member} joined")
    async def on_ready(self):
        print("Bot ready to work!")
    def __init__(self):
        self.intents = discord.Intents(messages = True, guilds = True, reactions = True, members = True, presences = True)
        self.bot = commands.Bot(command_prefix = '~rpg ', intents = intents)
intents = discord.Intents(messages = True, guilds = True, reactions = True, members = True, presences = True)
client = bot = commands.Bot(command_prefix = '~rpg ', intents = intents)
@client.command(name='join')
async def jointothefun(context):
    keys = db.keys()
    rpgc = client.get_channel(811518285634863124)
    if context.message.channel == rpgc:
        if not f"{context.message.author.id}" in keys:            
            await context.message.channel.send("Hi "+str(context.message.author.mention))
            #not working code
            db[f"{context.message.author.id}"] = Player(100,0,0,0,0,1)
        else:
            await context.message.channel.send("Bruh you've joined already")
    else:
        await context.message.channel.send('Yo wrong channel!')
@client.command(name='stats')
async def stats(context):
    rpgc = client.get_channel(811518285634863124)
    if context.message.channel==rpgc:
      keys = db.keys()
      if str(context.message.author.id) in keys:
            embed=db[str(context.message.author.id)].displayEquipment
            await context.send(embed=embed)
      else:
            await context.message.channel.send("Join first to access stats!")
    else:
        await context.message.channel.send(f"XD {context.message.author.mention} to nie ten kanał! Pisz na #rpg")

@client.command()
async def ping(ctx):
    await ctx.send("Pong!")
startup()
#yes i know that will not work but it's private i guess it's obvious
client.run("my bot token")

播放器类

from item_class import Weapon
import discord
class Player:
  def __init__(self,h,m,de,c,t,dm):
    self.hp=h
    self.mana=m
    self.defense=de
    self.coins=c
    self.truecoins=t
    self.weapon=Weapon("Stick",10,1,1,100,1,0)
    self.dmg=dm+self.weapon.dmg
    self.itlist=[]
  def addItemToEq(self,it):
    self.itlist.append(it)
  def displayEquipment(self,client,context):
    embed = discord.Embed(
      title="Inventory",colour=discord.Colour.Green)
    for i in self.itlist:
      if type(i)==Weapon:
        embed.add_field(i.self.name,"Weapon",False)
      else:
        embed.add_field(i.self.name,"Item",False)
    return embed

物品类别

import random
class Item:
    def __init__(self,name):
        self.name = name
    def use(self):
        print("its normal item bruh")
class Food(Item):
    def __init__(self,name,nutrition):
        self.name=name
        self.hpboost=nutrition
class Weapon(Item):
    def __init__(self,name,durablity,dmgboost,critchcmin,critchcmax,crit,boost):
        self.name=name
        self.durablity=durablity
        self.dmg=dmgboost
        self.critmin=critchcmin
        self.critmax=critchcmax
        self.critdmg=crit
        self.fnc=boost
    def attack(self):
        print(self.dmg)
        print(str(self.calcCrit()))
        self.durablity-=1
    def calcCrit(self):
        if random.randint(self.critmin,self.critmax)<=self.critmax/2:
            return True
        else:
            return False
    def useBoost(self):
        self.boost()

如果有人能帮助我,我将不胜感激:)

【问题讨论】:

  • 请不要包含您的整个代码,只包含相关代码,在这种情况下是导入、导入的对象和错误

标签: python discord.py


【解决方案1】:

正如here 的回答,replit 数据库的values 必须是 JSON 可序列化的。这意味着,您必须(很可能)传递 dict 而不是类对象,但是您将无法使用该对象的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 2016-02-15
    • 2014-02-05
    • 2015-07-14
    • 2020-01-07
    • 2013-06-23
    • 2021-09-01
    相关资源
    最近更新 更多