首页 > 解决方案 > 当一个类的对象在没有任何括号的情况下输入并运行时,它是如何在 Python REPL 或 Jupyter Notebook 中打印出来的

问题描述

背景:我正在使用 jupyter 笔记本中的 SymPy 模块。我想创建 sympy 的 Matrix 类的子/子类(实际上是 sympy.matrices.dense.MutableDenseMatrix)。

我写这个=>

import sympy as sym
class Mat(sym.Matrix):
  def __init__(self,a):
    self.a = super(a)

然后我在一个单独的单元格中调用以下内容

X=Mat([[1,2,3]])

这给出了一个错误

TypeError                                 
Traceback (most recent call last)
<ipython-input-154-9d0dfad5081f> in <module>
----> 1 X= Mat([[1,2,3]])

<ipython-input-153-41d7b2cc4dd1> in __init__(self, a)
      1 class Mat(sym.Matrix):
      2     def __init__(self,a):
----> 3         self.a = super(a)

TypeError: super() argument 1 must be type, not list

不知道这个原因我试过这个

class Mat:
    def __init__(self,a):
        self.a = sym.Matrix(a)

然后任务通过了。

现在我单独在 Next Cell 中运行它(假设这就像只是执行Name为简单起见)

X

并得到了输出

<__main__.Mat at 0x7f80b77f8b80>

但我期待

[1 2 3]

或者

Matrix([[1, 2, 3]])

当我创建一个常规的sym.Matrix对象并执行它时,这些分别是 Jupyter Notebook 和 Python REPL 中的输出

注意:我知道存在,__str____repr__只有在我使用时才有帮助print(X)

注意:我尝试定义__call__

def __call__(self):
  return self.a

但它只有在我先执行X=X()然后执行时才有效X

所以我的问题是,仅执行对象名称时调用的内部方法(可能是魔术方法)是什么?如果将来我创建一个没有继承的类(所以我不必须回退到相同的超类方法)

标签: pythonjupyter-notebookread-eval-print-loop

解决方案


通过查看我们拥有的文档:

在 Python 中,对象可以使用_repr _ 方法声明其文本表示。IPython 扩展了这个想法,并允许对象声明其他丰富的表示,包括:

_repr_html_:将原始 HTML 作为字符串或元组返回(见下文)。

_repr_json_:返回一个 JSONable 字典或一个元组(见下文)。

_repr_jpeg_:返回原始 JPEG 数据或元组(见下文)。

_repr_png_:返回原始 PNG 数据或元组(见下文)。

_repr_svg_:将原始 SVG 数据作为字符串或元组返回(见下文)。

_repr_latex_:以“$”包围的字符串或元组(见下文)返回 LaTeX 命令。

_repr_mimebundle_:返回包含映射的完整 mimebundle

作为补充,这个 SO question似乎是相关的。

一个工作片段应该是这样的:

import sympy as sym
class Mat(sym.Matrix):
  def __init__(self,a):
    self.a = sym.Matrix(a)
  def _repr_html_(self):
        return f"<p><h1>{self.a.__repr__()}</h1></p>"

这会产生类似的输出: 在此处输入图像描述


推荐阅读