自定义Sympy Function子类如何直接接收含空格的字符串参数?
自定义Sympy Function子类如何直接接收含空格的字符串参数?
这个问题我之前也碰到过,其实核心原因是Sympy的Function类在实例化时的默认行为导致的,咱们一步步来拆解和解决:
首先说为什么直接传'a b'会报错:Sympy的Function在创建实例时,会自动对传入的所有参数调用sympify()方法,这个方法会尝试把输入解析成Sympy表达式。而带空格的字符串'a b'会被它当成乘法表达式a * b来解析,但此时a和b都不是已定义的Symbol,自然就抛出了"could not parse"的错误。
你提到用testClass(sp.Symbol('a b'))可以正常工作,这是因为Symbol本身支持带空格的名称,直接传入Symbol对象时,sympify()不会再做额外解析。但如果想省略手动包装Symbol的步骤,确实需要重写Function的__new__方法——因为Sympy的核心类大多是不可变对象,实例创建逻辑主要在__new__而不是__init__里。
下面给你两种实用的解决方案:
方案1:自动将字符串参数转为Symbol
如果你的需求只是让类能直接接收带空格的字符串,自动处理成Symbol参数,重写__new__时直接完成转换即可:
import sympy as sp class testClass(sp.Function): @classmethod def __new__(cls, name, **kwargs): # 手动将输入字符串转为Symbol,跳过默认的sympify解析逻辑 sym_symbol = sp.Symbol(name) # 调用父类的__new__创建实例 return super().__new__(cls, sym_symbol, **kwargs) # 现在可以直接传带空格的字符串了 a = testClass('a b') print(a) # 输出:testClass(a b)
方案2:同时保留原始字符串属性
如果你的类需要额外持有原始的字符串(比如后续要用到这个带空格的名称),可以在实例创建后给它添加一个属性:
import sympy as sp class testClass(sp.Function): def __new__(cls, name, **kwargs): sym_symbol = sp.Symbol(name) # 创建实例 instance = super().__new__(cls, sym_symbol, **kwargs) # 给实例绑定原始字符串属性 instance.original_name = name return instance a = testClass('a b') print(a) # 输出:testClass(a b) print(a.original_name) # 输出:'a b'
这两种方案都能绕过Function默认的参数解析逻辑,让你直接传入带空格的字符串,不用手动包装Symbol。本质上是通过重写__new__接管了参数的预处理流程,适配你的自定义需求。
备注:内容来源于stack exchange,提问作者Michael Gfrerer
相关产品推荐
相关产品推荐

