You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.py中扩展discord.Guild类遇__dict__报错,求解决方案

解决方案:扩展discord.Guild类(基于原实例创建子类实例)

错误原因

discord.py中的discord.Guild类使用了__slots__优化内存占用,这类对象不会自动生成__dict__属性,直接赋值obj.__dict__ = guild.__dict__会触发AttributeError。


方案一:继承+手动复制slots属性

通过显式声明子类的__slots__,逐个复制父类实例的属性值实现扩展:

from typing import Self
from models.dataclasses import Settings
import discord


class Guild(discord.Guild):
    __slots__ = ('settings', 'is_blacklisted') + discord.Guild.__slots__
    settings: Settings
    is_blacklisted: bool

    @classmethod
    def from_discord(
        cls, guild: discord.Guild, settings: Settings, is_blacklisted: bool = False
    ) -> Self:
        obj: Self = cls.__new__(cls)
        
        # 遍历父类slots,逐个复制属性
        for slot in discord.Guild.__slots__:
            try:
                setattr(obj, slot, getattr(guild, slot))
            except AttributeError:
                # 忽略无法访问的内部属性
                pass
        
        obj.settings = settings
        obj.is_blacklisted = is_blacklisted
        
        return obj

注意事项

  • 子类必须显式包含父类的所有__slots__,否则会因属性缺失报错。
  • 用try-except处理只读或内部属性的访问异常,保证代码兼容性。

方案二:组合模式(推荐)

不直接继承discord.Guild,而是将其作为内部成员存储,通过属性代理实现扩展,避免继承slots类的潜在问题:

from typing import Any
from models.dataclasses import Settings
import discord


class Guild:
    def __init__(self, guild: discord.Guild, settings: Settings, is_blacklisted: bool = False):
        self._guild = guild
        self.settings = settings
        self.is_blacklisted = is_blacklisted

    # 自动代理所有未定义的属性/方法到内部的discord.Guild实例
    def __getattr__(self, name: str) -> Any:
        return getattr(self._guild, name)

优势

  • 无需关注discord.Guild的内部__slots__结构,兼容性更强。
  • 代码结构清晰,自定义属性与原类属性分离,易于维护。
  • 使用体验和直接操作discord.Guild完全一致,原类所有方法、属性均可正常调用。

内容的提问来源于stack exchange,提问作者Tumpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:27:50