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
相关产品推荐
相关产品推荐

