在Jupyter Notebook中显示未在if-else块中显示的HTML类

mwecs4sa  于 2023-04-18  发布在  其他
关注(0)|答案(1)|浏览(136)

我使用这个类来表示.ipynb文件中的 Dataframe :

# Handy class for DataFrame viz
class display(object):
    '''
    Display HTML representation of multiple objects
    '''
    
    template = '''<div style="float: left; padding: 10px;">
                  <p style='font-family:"Courier New", Courier, monospace'>{0}</p>{1}
                  </div>'''
    
    def __init__(self, *args):
        self.args = args
        
    def _repr_html_(self):
        return '\n'.join(self.template.format(a, eval(a)._repr_html_()) for a in self.args)
    
    def __repr__(self):
        return '\n\n'.join(a + '\n' + repr(eval(a)) for a in self.args)

这个类在if-else块中不工作,我不明白为什么。
有没有人能给予个解释?提前谢谢!
用于复制问题的块:

import pandas as pd

# Handy class for DataFrame viz

# Create a sample DataFrame with 3 rows and 5 columns
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9],
    'D': [10, 11, 12],
    'E': [13, 14, 15]
})

# Display the DataFrame
display('df')

>>>

df

A   B   C   D   E
0   1   4   7   10  13
1   2   5   8   11  14
2   3   6   9   12  15
inside = True

if inside:
    display('df')

>>>
ktecyv1j

ktecyv1j1#

我认为这可能是因为if inside if-else的缩进使它不在单元格最后一行的最外面的点上,所以IPython/Jupyter没有使用InteractiveShell来“显示”它,使用它对单元格中最后一个未缩进对象的特殊处理,看看last_expr是如何默认为InteractiveShell.ast_node_interactivityhere的。以同样的方式...假设你在一个单元格中运行以下代码:

a = 4
a

这将把4显示为Out
但是如果在下一个单元格中执行以下操作,它将不会显示4

inside = True

if inside:
    a

IPython / Jupyter应用于最后一行上的项的花哨显示处理不会被应用,因为它不是该行上评估的最外面的项,因此不会被传递给IPython的花哨表示处理。(或者至少我是这么想的。见托马斯·K'这里的解释是,当表达式在for循环中时,它只在单元格的末尾显示裸表达式,因此缩进类似于if-else。)我想这反映了你当时在做什么,也许?
但这个很有效

from IPython.display import display
inside = True

if inside:
    display(a)

您可以这样做,以强制应用它将应用的奇特处理,如果您只是将a放入一个单元格并运行它。

或者,如果您首先调整`InteractiveShell.ast_node_interactivity的设置,则可以使以下内容正常工作:

inside = True

if inside:
    a

在单独的单元格中尝试此操作之前,请运行以下命令之一:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "last"
  • 或者-
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

(因为需要在运行单元格之前运行并应用它,所以不能在要运行if inside:的单元格中添加代码来调整InteractiveShell.ast_node_interactivity。)

***选项A:****调整InteractiveShell.ast_node_interactivity以尝试修复您正在执行的操作 *:

因此,为了使您的原始示例代码正常工作,您可以选择在运行您的原始帖子中的inside = True代码块之前首先运行以下代码作为单元格本身:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "last"

***备选选项B:****应用use if IPython的显示来尝试修复您正在执行的操作 *:

所以为了让你的dataframe显示类的版本工作,让我们不要隐藏IPython的display,因为我们需要它。所以让这个单元格:

class spec_display(object):
    '''
    Display HTML representation of multiple objects
    '''
    
    template = '''<div style="float: left; padding: 10px;">
                  <p style='font-family:"Courier New", Courier, monospace'>{0}</p>{1}
                  </div>'''
    
    def __init__(self, *args):
        self.args = args
        
    def _repr_html_(self):
        return '\n'.join(self.template.format(a, eval(a)._repr_html_()) for a in self.args)
    
    def __repr__(self):
        return '\n\n'.join(a + '\n' + repr(eval(a)) for a in self.args)

然后作为一个单独的单元格,它的工作方式与原始单元格相同:

import pandas as pd

# Handy class for DataFrame viz

# Create a sample DataFrame with 3 rows and 5 columns
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9],
    'D': [10, 11, 12],
    'E': [13, 14, 15]
})

# Display the DataFrame
spec_display('df')

除了现在在另一个单元格中,你看到的不工作的东西可以通过显式调用IPython的display来工作,就像我们可以使用它在一个单元格中打印多个 Dataframe 并添加标题一样(我会回到这个问题):

from IPython.display import display
inside = True

if inside:
    display(spec_display('df'))

最后,我在上面提到过,你可以使用IPython的display从一个单元格中的代码打印多个 Dataframe ,并添加标题,所有这些都在一个输出单元格中。(我提出这个是因为我在你的代码的注解中看到,“显示多个对象的HTML表示”。)示例:

import pandas as pd
df1 = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9],
    'D': [10, 11, 12],
    'E': [13, 14, 15]
})

df2 = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9],
    'D': [10, 11, 12],
    'E': [13, 14, 15]
})
from IPython.display import display, HTML
display(HTML('<b>Dataframe One:</b>'))
display(df1)
display(HTML('<b>Dataframe Two:</b>'))
display(df2)

我们可以告诉IPython如何处理事情,而不依赖于它通常只应用于最后一行的未缩进的final对象的特殊处理。

相关问题