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 表示表达式代表哪种数学对象。你可以通过 \(.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
NumberKind

SymPy 的 \(Set\) 和 kind 不兼容。

>>> 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\) 是对象的头部,用于递归遍历表达式树。

>>> 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 对象。在用此属性对对象进行分类时,请记住这一点。有关详细信息,请参阅 教程-操作