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