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

如何创建两个同名但独立的SymPy Symbol对象?

SymPy自定义Symbol类同名实例覆盖属性的问题解决

你观察的没错,SymPy的Symbol类内部使用了对象缓存机制——当创建同名符号时,会返回已存在的实例,而不是新创建对象。所以第二次调用MySymbol('x', 200)时,拿到的是第一次创建的symbolx实例,随后覆盖了它的description属性,最终两个变量指向同一个对象,输出结果都是200。

方案1:禁用Symbol的缓存机制

修改自定义类的__new__方法,调用父类的__new__时传入cache=False参数,强制每次创建新实例:

from sympy import Symbol

class MySymbol(Symbol):
    def __new__(cls, symbol, description):
        # 传入cache=False禁用缓存,每次生成新实例
        obj = super().__new__(cls, symbol, cache=False)
        obj.description = description
        return obj

symbolx = MySymbol('x', 100)
symbolx2 = MySymbol('x', 200)
symboly = MySymbol('y', 300)

print(symbolx.description)  # 输出100
print(symbolx2.description) # 输出200
print(symboly.description)  # 输出300

优点:不改变SymPy默认的符号相等逻辑,后续符号运算不受影响;实现简单。

方案2:修改实例的相等性判断逻辑(谨慎使用)

如果需要保留缓存,但希望不同描述的同名符号被视为不同实例,可以重写__eq__和__hash__方法,将description纳入相等性判断的依据:

from sympy import Symbol

class MySymbol(Symbol):
    def __new__(cls, symbol, description):
        obj = super().__new__(cls, symbol)
        obj.description = description
        return obj
    
    def __eq__(self, other):
        # 先判断是否为MySymbol实例,再同时比较符号名和描述
        if isinstance(other, MySymbol):
            return super().__eq__(other) and self.description == other.description
        return super().__eq__(other)
    
    def __hash__(self):
        # 将符号名的哈希和描述的哈希组合作为实例的哈希值
        return hash((super().__hash__(), self.description))

symbolx = MySymbol('x', 100)
symbolx2 = MySymbol('x', 200)
symboly = MySymbol('y', 300)

print(symbolx.description)  # 输出100
print(symbolx2.description) # 输出200
print(symboly.description)  # 输出300
print(symbolx == symbolx2)  # 输出False,视为不同符号

注意:该方案会改变SymPy默认的符号相等逻辑,可能导致后续符号运算中,同名但不同描述的符号无法被识别为同一个变量,仅适合不需要将这些符号视为同一变量的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:24:24