SymPy 对象分类¶
有多种方法可以对 SymPy 对象进行分类。
类¶
与 Python 中的任何其它对象一样,SymPy 表达式是类的实例。您可以使用内置的 \(type()\) 函数获取对象的类,并使用 \(isinstance()\) 函数进行检查。
>>> from sympy import Add
>>> from sympy.abc import x,y
>>> type(x + y)
<class 'sympy.core.add.Add'>
>>> isinstance(x + y, Add)
True
类仅表示对象的编程结构,并不区分它们之间的数学差异。例如,数字的积分和矩阵的积分都属于 \(Integral\) 类,尽管前者是数字,后者是矩阵。
>>> from sympy import MatrixSymbol, Integral
>>> A = MatrixSymbol('A', 2, 2)
>>> type(Integral(1, x))
<class 'sympy.integrals.integrals.Integral'>
>>> type(Integral(A, x))
<class 'sympy.integrals.integrals.Integral'>
类型¶
类型表示表达式所代表的数学对象。您可以使用 \(.kind\) 属性获取表达式的类型。
>>> Integral(1, x).kind
NumberKind
>>> Integral(A, x).kind
MatrixKind(NumberKind)
此结果表明 \(Integral(1, x)\) 是数字,而 \(Integral(A, x)\) 是具有数字元素的矩阵。
由于类无法保证捕捉到这种差异,因此对象的类型非常重要。例如,如果您正在构建一个仅针对数字设计的函数或类,您应该考虑使用 \(NumberKind\) 过滤参数,以防止用户无意中传递不支持的对象,例如 \(Integral(A, x)\)。
为了提高性能,集合理论没有在类型系统中实现。例如,
\(NumberKind\) 无法区分实数和复数。
>>> from sympy import pi, I >>> pi.kind NumberKind >>> I.kind NumberKindSymPy 的 \(Set\) 和类型不兼容。
>>> from sympy import S >>> from sympy.core.kind import NumberKind >>> S.Reals.is_subset(S.Complexes) True >>> S.Reals.is_subset(NumberKind) Traceback (most recent call last): ... ValueError: Unknown argument 'NumberKind'
集合和假设¶
如果您希望以严格的数学方式对对象进行分类,则可能需要使用 SymPy 的集合和假设。
>>> from sympy import ask, Q
>>> S.One in S.Reals
True
>>> ask(Q.even(2*x), Q.odd(x))
True
有关更多信息,请参阅 \(assumptions\) 模块和 \(sets\) 模块。
func¶
\(func\) 是对象的头部,用于递归遍历表达式树。
>>> Add(x + y).func
<class 'sympy.core.add.Add'>
>>> Add(x + x).func
<class 'sympy.core.mul.Mul'>
>>> Q.even(x).func
<class 'sympy.assumptions.assume.AppliedPredicate'>
正如您所见,结果头部可能是一个类或另一个 SymPy 对象。当您使用此属性对对象进行分类时,请牢记这一点。有关详细信息,请参阅 高级表达式操作。