pywebio.output — 输出模块

输出内容到用户浏览器

本模块提供了一系列函数来输出不同形式的内容到用户浏览器,并支持灵活的输出控制。

函数清单

函数

简介

输出域Scope

set_scope

创建一个新的scope.

get_scope

获取当前运行时scope栈中的scope名

clear

清空scope内容

remove

移除Scope

scroll_to

将页面滚动到 scope Scope处

use_scope

开启/进入输出域

内容输出

put_text

输出文本

put_markdown

输出Markdown

put_html

输出Html

put_link

输出链接

put_processbar

输出进度条

set_processbar

设置进度条进度

put_loading

输出加载提示

put_code

输出代码块

put_table

输出表格

put_buttons

输出一组按钮,并绑定点击事件

put_image

输出图片

put_file

显示一个文件下载链接

put_collapse

输出可折叠的内容

put_scrollable

固定高度内容输出区域,内容超出则显示滚动条

put_widget

输出自定义的控件

其他交互

toast

显示一条通知消息

popup

显示弹窗

close_popup

关闭正在显示的弹窗

布局与样式

put_row

使用行布局输出内容

put_column

使用列布局输出内容

put_grid

使用网格布局输出内容

span

put_table()put_grid() 中设置内容跨单元格

style

自定义输出内容的css样式

其他

output

内容占位符

输出域Scope

pywebio.output.set_scope(name, container_scope=- 1, position=- 1, if_exist=None)[源代码]

创建一个新的scope.

参数
  • name (str) – scope名

  • container_scope (int/str) – 此scope的父scope. 可以直接指定父scope名或使用 Scope 常量. scope不存在时,不进行任何操作.

  • position (int) – 在父scope中创建此scope的位置. OutputPosition.TOP : 在父scope的顶部创建, OutputPosition.BOTTOM : 在父scope的尾部创建

  • if_exist (str) –

    已经存在 name scope 时如何操作:

    • None 表示不进行任何操作

    • 'remove' 表示先移除旧scope再创建新scope

    • 'clear' 表示将旧scope的内容清除,不创建新scope

    默认为 None

pywebio.output.get_scope(stack_idx=- 1)[源代码]

获取当前运行时scope栈中的scope名

参数

stack_idx (int) –

需要获取的scope在scope栈中的索引值。默认返回当前scope名

-1表示当前scope,-2表示进入当前scope前的scope,依次类推;0表示 ROOT scope

返回

返回Scope栈中对应索引的scope名,索引错误时返回None

pywebio.output.clear(scope=- 1)[源代码]

清空scope内容

参数

scope (int/str) – 可以直接指定scope名或使用 Scope 常量

pywebio.output.remove(scope=- 1)[源代码]

移除Scope

pywebio.output.scroll_to(scope, position=Position.TOP)[源代码]

将页面滚动到 scope Scope处

参数
  • scope (str/int) – Scope名

  • position (str) –

    将Scope置于屏幕可视区域的位置。可用值:

    • Position.TOP : 滚动页面,让Scope位于屏幕可视区域顶部

    • Position.MIDDLE : 滚动页面,让Scope位于屏幕可视区域中间

    • Position.BOTTOM : 滚动页面,让Scope位于屏幕可视区域底部

pywebio.output.use_scope(name=None, clear=False, create_scope=True, **scope_params)[源代码]

scope的上下文管理器和装饰器。用于创建一个新的输出域并进入,或进入一个已经存在的输出域。

参见 用户手册-use_scope()

参数
  • name – scope名. 若为None则生成一个全局唯一的scope名.(以上下文管理器形式的调用时,上下文管理器会返回scope名)

  • clear (bool) – 在进入scope前是否要清除scope里的内容

  • create_scope (bool) – scope不存在时是否创建scope

  • scope_params – 创建scope时传入set_scope()的参数. 仅在 create_scope=True 时有效.

Usage

with use_scope(...) as scope_name:
    put_xxx()

@use_scope(...)
def app():
    put_xxx()

内容输出

pywebio.output.put_text(*texts, sep=' ', inline=False, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出文本内容

参数
  • texts – 要输出的内容。类型可以为任意对象,对非字符串对象会应用 str() 函数作为输出值。

  • sep (str) – 输出分隔符

  • inline (bool) – 文本行末不换行。默认换行

  • scope (int/str) –

    内容输出的目标scope,若scope不存在,则不进行任何输出操作。

    可以直接指定目标Scope名,或者使用int通过索引Scope栈来确定Scope:0表示最顶层也就是ROOT Scope,-1表示当前Scope,-2表示进入当前Scope的前一个Scope,…

  • position (int) –

    在scope中输出的位置。

    position>=0时表示输出到scope的第position个(从0计数)子元素的前面;position<0时表示输出到scope的倒数第position个(从-1计数)元素之后。

参数 scopeposition 的更多使用说明参见 用户手册

pywebio.output.put_markdown(mdcontent, strip_indent=0, lstrip=False, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出Markdown内容。

参数
  • mdcontent (str) – Markdown文本

  • strip_indent (int) – 对于每一行,若前 strip_indent 个字符都为空格,则将其去除

  • lstrip (bool) – 是否去除每一行开始的空白符

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

当在函数中使用Python的三引号语法输出多行内容时,为了排版美观可能会对Markdown文本进行缩进, 这时候,可以设置 strip_indentlstrip 来防止Markdown错误解析(但不要同时使用 strip_indentlstrip ):

# 不使用strip_indent或lstrip
def hello():
    put_markdown(r""" # H1
This is content.
""")

# 使用lstrip
def hello():
    put_markdown(r""" # H1
    This is content.
    """, lstrip=True)

# 使用strip_indent
def hello():
    put_markdown(r""" # H1
    This is content.
    """, strip_indent=4)
pywebio.output.put_html(html, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出Html内容。

与支持通过Html输出内容到 Jupyter Notebook 的库兼容。

参数
  • html – html字符串或实现了 IPython.display.HTML 接口的类的实例

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

输出链接到其他页面或PyWebIO App的超链接

参数
  • name (str) – 链接名称

  • url (str) – 链接到的页面地址

  • app (str) – 链接到的PyWebIO应用名

  • new_window (bool) – 是否在新窗口打开链接

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

urlapp 参数必须指定一个但不可以同时指定

pywebio.output.put_processbar(name, init=0, label=None, auto_close=False, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出进度条

参数
  • name (str) – 进度条名称,为进度条的唯一标识

  • init (float) – 进度条初始值. 进度条的值在 0 ~ 1 之间

  • label (str) – 进度条显示的标签. 默认为当前进度的百分比

  • auto_close (bool) – 是否在进度完成后关闭进度条

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.set_processbar(name, value, label=None)[源代码]

设置进度条进度

参数
  • name (str) – 进度条名称

  • value (float) – 进度条的值. 范围在 0 ~ 1 之间

  • label (str) – 进度条显示的标签. 默认为当前进度的百分比

pywebio.output.put_loading(shape='border', color='dark', scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

显示一个加载提示

参数
  • shape (str) – 加载提示的形状, 可选值: 'border' (默认,旋转的圆环)、 'grow' (大小渐变的圆点)

  • color (str) – 加载提示的颜色, 可选值: 'primary''secondary''success''danger''warning''info''light''dark' (默认)

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

注解

可以通过 style() 设置加载提示的尺寸:

style(put_loading(), 'width:4rem; height:4rem')
pywebio.output.put_code(content, language='', scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出代码块

参数
  • content (str) – 代码内容

  • language (str) – 代码语言

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.put_table(tdata, header=None, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出表格

参数
  • tdata (list) – 表格数据。列表项可以为 list 或者 dict , 单元格的内容可以为字符串或 put_xxx 类型的输出函数。 数组项可以使用 span() 函数来设定单元格跨度。

  • header (list) –

    设定表头。 当 tdata 的列表项为 list 类型时,若省略 header 参数,则使用 tdata 的第一项作为表头。表头项可以使用 span() 函数来设定单元格跨度。

    tdata 为字典列表时,使用 header 指定表头顺序,不可省略。 此时, header 格式可以为 <字典键>列表 或者 (<显示文本>, <字典键>) 列表。

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

使用示例:

# 'Name'单元格跨2行、'Address'单元格跨2列
put_table([
    [span('Name',row=2), span('Address', col=2)],
    ['City', 'Country'],
    ['Wang', 'Beijing', 'China'],
    ['Liu', 'New York', 'America'],
])

# 单元格为 ``put_xxx`` 类型的输出函数
put_table([
    ['Type', 'Content'],
    ['html', put_html('X<sup>2</sup>')],
    ['text', '<hr/>'],
    ['buttons', put_buttons(['A', 'B'], onclick=...)],  
    ['markdown', put_markdown('`Awesome PyWebIO!`')],
    ['file', put_file('hello.text', b'')],
    ['table', put_table([['A', 'B'], ['C', 'D']])]
])

# 设置表头
put_table([
    ['Wang', 'M', 'China'],
    ['Liu', 'W', 'America'],
], header=['Name', 'Gender', 'Address'])

# dict类型的表格行
put_table([
    {"Course":"OS", "Score": "80"},
    {"Course":"DB", "Score": "93"},
], header=["Course", "Score"])  # or header=[("课程", "Course"), ("得分" ,"Score")]

0.3 新版功能: 单元格的内容支持 put_xxx 类型的输出函数

pywebio.output.span(content, row=1, col=1)[源代码]

用于在 put_table()put_grid() 中设置内容跨单元格

参数
  • content – 单元格内容

  • row (int) – 竖直方向跨度, 即:跨行的数目

  • col (int) – 水平方向跨度, 即:跨列的数目

Example

put_table([
    ['C'],
    [span('E', col=2)],  # 'E' 跨2列
], header=[span('A', row=2), 'B'])  # 'A' 跨2行

put_grid([
    [put_text('A'), put_text('B')],
    [span(put_text('A'), col=2)],  # 'A' 跨2列
])
pywebio.output.put_buttons(buttons, onclick, small=None, link_style=False, scope=- 1, position=- 1, **callback_options)pywebio.io_ctrl.Output[源代码]

输出一组按钮,并绑定点击事件

参数
  • buttons (list) –

    按钮列表。列表项的可用形式有:

    • dict: {label:选项标签, value:选项值}

    • tuple or list: (label, value)

    • 单值: 此时label和value使用相同的值

    其中, value 可以为任意可json序列化的对象。使用dict类型的列表项时,支持使用 color key设置按钮颜色,可选值为 primarysecondarysuccessdangerwarninginfolightdark

    例如:

    put_buttons([dict(label='primary', value='p', color='primary')], onclick=...)  
    

  • onclick (Callable / list) –

    按钮点击回调函数. onclick 可以是函数或者函数组成的列表.

    onclick 为函数时, 签名为 onclick(btn_value). btn_value 为被点击的按钮的 value

    onclick 为列表时,列表内函数的签名为 func(). 此时,回调函数与 buttons 一一对应

    Tip: 可以使用 functools.partial 来在 onclick 中保存更多上下文信息.

    Note: 当使用 基于协程的会话实现 时,回调函数可以为协程函数.

  • small (bool) – 是否显示小号按钮,默认为False

  • link_style (bool) – 是否将按钮显示为链接样式,默认为False

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

  • callback_options

    回调函数的其他参数。根据选用的 session 实现有不同参数

    CoroutineBasedSession 实现
    • mutex_mode: 互斥模式。默认为 False 。若为 True ,则在运行回调函数过程中,无法响应当前按钮组的新点击事件,仅当 onclick 为协程函数时有效

    ThreadBasedSession 实现
    • serial_mode: 串行模式模式。默认为 False ,此时每次触发回调,回调函数会在新线程中立即执行。

    对于开启了serial_mode的回调,都会在会话内的一个固定线程内执行,当会话运行此回调时,其他所有新的点击事件的回调(包括 serial_mode=False 的回调)都将排队等待当前点击事件运行完成。 如果回调函数运行时间很短,可以开启 serial_mode 来提高性能。

使用示例:

from functools import partial

def row_action(choice, id):
    put_text("You click %s button with id: %s" % (choice, id))

put_buttons(['edit', 'delete'], onclick=partial(row_action, id=1))

def edit():
    put_text("You click edit button")
def delete():
    put_text("You click delete button")

put_buttons(['edit', 'delete'], onclick=[edit, delete])

注意

在PyWebIO会话(关于会话的概念见 Server与script模式 )结束后,事件回调也将不起作用, 可以在任务函数末尾处使用 pywebio.session.hold() 函数来将会话保持,这样在用户关闭浏览器页面前,事件回调将一直可用。

pywebio.output.put_image(src, format=None, title='', width=None, height=None, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出图片。

参数
  • src – 图片内容. 类型可以为字符串类型的URL或者是 bytes-like object 或者为 PIL.Image.Image 实例

  • title (str) – 图片描述

  • width (str) – 图像的宽度,可以是CSS像素(数字px)或者百分比(数字%)。

  • height (str) – 图像的高度,可以是CSS像素(数字px)或者百分比(数字%)。可以只指定 width 和 height 中的一个值,浏览器会根据原始图像进行缩放。

  • format (str) – 图片格式。如 png , jpeg , gif 等, 仅在 src 为非URL时有效

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.put_file(name, content, label=None, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

显示一个文件下载链接。 在浏览器上的显示为一个以文件名为名的链接,点击链接后浏览器自动下载文件。

参数
  • name (str) – 下载保存为的文件名

  • content – 文件内容. 类型为 bytes-like object

  • label (str) – 下载链接的显示文本,默认和文件名相同

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

注意

在PyWebIO会话(关于会话的概念见 Server与script模式 )结束后,使用 put_file() 输出的文件也将无法下载,可以在任务函数末尾处使用 pywebio.session.hold() 函数来将会话保持,这样在用户关闭浏览器页面前, 文件下载将一直可用。

pywebio.output.put_collapse(title, content, open=False, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出可折叠的内容

参数
  • title (str) – 内容标题

  • content (list/str/put_xxx()) – 内容可以为字符串或 put_xxx 类输出函数的返回值,或者由它们组成的列表。

  • open (bool) – 是否默认展开折叠内容。默认不展开内容

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.put_scrollable(content, max_height=400, horizon_scroll=False, border=True, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

固定高度内容输出区域,内容超出则显示滚动条

参数
  • content (list/str/put_xxx()) – 内容可以为字符串或 put_xxx 类输出函数的返回值,或者由它们组成的列表。

  • max_height (int) – 区域的最大高度(像素),内容超出次高度则使用滚动条

  • horizon_scroll (bool) – 是否显示水平滚动条

  • border (bool) – 是否显示边框

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.put_widget(template, data, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

输出自定义的控件

参数
  • template – html模版,使用 mustache.js 语法

  • data (dict) –

    渲染模版使用的数据.

    数据可以包含输出函数( put_xxx() )的返回值, 可以使用 pywebio_output_parse 函数来解析 put_xxx() 内容;对于字符串输入, pywebio_output_parse 会将解析成文本.

    ⚠️:使用 pywebio_output_parse 函数时,需要关闭mustache的html转义: {{& pywebio_output_parse}} , 参见下文示例.

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

Example

tpl = '''
<details>
    <summary>{{title}}</summary>
    {{#contents}}
        {{& pywebio_output_parse}}
    {{/contents}}
</details>
'''

put_widget(tpl, {
    "title": 'More content',
    "contents": [
        'text',
        put_markdown('~~删除线~~'),
        put_table([
            ['商品', '价格'],
            ['苹果', '5.5'],
            ['香蕉', '7'],
        ])
    ]
})

其他交互

pywebio.output.toast(content, duration=2, position='center', color='info', onclick=None)[源代码]

显示一条通知消息

参数
  • content (str) – 通知内容

  • duration (float) – 通知显示持续的时间,单位为秒。 0 表示不自动关闭(此时消息旁会显示一个关闭图标,用户可以手动关闭消息)

  • position (str) – 通知消息显示的位置,可以为 'left' / 'center' / 'right'

  • color (str) – 通知消息的背景颜色,可以为 'info' / 'error' / 'warn' / 'success' 或以 '#' 开始的十六进制颜色值

  • onclick (callable) –

    点击通知消息时的回调函数,回调函数不接受任何参数。

    Note: 当使用 基于协程的会话实现 时,回调函数可以为协程函数.

Example:

def show_msg():
    put_text("Some messages...")

toast('New messages', position='right', color='#2188ff', duration=0, onclick=show_msg)
pywebio.output.popup(title, content, size=PopupSize.NORMAL, implicit_close=True, closable=True)[源代码]

显示弹窗

⚠️: PyWebIO不允许同时显示多个弹窗,在显示新弹窗前,会自动关闭页面上存在的弹窗。可以使用 close_popup() 主动关闭弹窗

参数
  • title (str) – 弹窗标题

  • content (list/str/put_xxx()) – 弹窗内容. 可以为字符串或 put_xxx 类输出函数的返回值,或者为它们组成的列表。

  • size (str) –

    弹窗窗口大小,可选值:

    • LARGE : 大尺寸

    • NORMAL : 普通尺寸

    • SMALL : 小尺寸

  • implicit_close (bool) – 是否可以通过点击弹窗外的内容或按下 Esc 键来关闭弹窗

  • closable (bool) – 是否可由用户关闭弹窗. 默认情况下,用户可以通过点击弹窗右上角的关闭按钮来关闭弹窗, 设置为 False 时弹窗仅能通过 popup_close() 关闭, implicit_close 参数被忽略.

支持直接传入内容、上下文管理器、装饰器三种形式的调用

  • 直接传入内容:

  • 作为上下文管理器使用:

上下文管理器会开启一个新的输出域并返回Scope名,上下文管理器中的输出调用会显示到弹窗上。 上下文管理器退出后,弹窗并不会关闭,依然可以使用 scope 参数输出内容到弹窗。

  • 作为装饰器使用:

pywebio.output.close_popup()[源代码]

关闭当前页面上正在显示的弹窗

布局与样式

pywebio.output.put_row(content, size=None, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

使用行布局输出内容. 内容在水平方向从左往右排列成一行

参数
  • content (list) – 子元素列表, 列表项为 put_xxx() 调用或者 None , None 表示空白列间距

  • size (str) –

    用于指示子元素的宽度, 为空格分割的宽度值列表.
    宽度值需要和 content 中子元素一一对应( None 子元素也要对应宽度值).
    size 默认给 None 元素分配10像素宽度,将剩余元素平均分配宽度.

    宽度值可用格式:

    • 像素值: 例如: 100px

    • 百分比: 表示占可用宽度的百分比. 例如: 33.33%

    • fr 关键字: 表示比例关系, 2fr 表示的宽度为 1fr 的两倍

    • auto 关键字: 表示由浏览器自己决定长度

    • minmax(min, max) : 产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。 例如: minmax(100px, 1fr) 表示长度不小于100px,不大于1fr

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

Example

put_row([put_code('A'), None, put_code('B')])  # 左右两个等宽度的代码块,中间间隔10像素

put_row([put_code('A'), None, put_code('B')], size='40% 10px 60%')  # 左右两代码块宽度比2:3, 和size='2fr 10px 3fr'等价
pywebio.output.put_column(content, size=None, scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

使用列布局输出内容. 内容在竖直方向从上往下排列成一列

参数
  • content (list) – 子元素列表, 列表项为 put_xxx() 调用或者 None , None 表示空白行间距

  • size (str) – 用于指示子元素的高度, 为空格分割的高度值列表. 可用格式参考 put_row() 函数的 size 参数注释.

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

pywebio.output.put_grid(content, cell_width='auto', cell_height='auto', cell_widths=None, cell_heights=None, direction='row', scope=- 1, position=- 1)pywebio.io_ctrl.Output[源代码]

使用网格布局输出内容

参数
  • content – 输出内容. put_xxx() / None 组成的二维数组, None 表示空白. 数组项可以使用 span() 函数设置元素在网格的跨度.

  • cell_width (str) – 网格元素的宽度. 宽度值格式参考 put_row() 函数的 size 参数注释.

  • cell_height (str) – 网格元素的高度. 高度值格式参考 put_row() 函数的 size 参数注释.

  • cell_widths (str) – 网格每一列的宽度. 宽度值用空格分隔. 不可以和 cell_width 参数同时使用. 宽度值格式参考 put_row() 函数的 size 参数注释.

  • cell_heights (str) – 网格每一行的高度. 高度值用空格分隔. 不可以和 cell_height 参数同时使用. 高度值格式参考 put_row() 函数的 size 参数注释.

  • direction (str) –

    排列方向. 为 'row''column' .

    'row' 时表示,content中的每一个子数组代表网格的一行;
    'column' 时表示,content中的每一个子数组代表网格的一列.

  • scope, position (int) – 与 put_text 函数的同名参数含义一致

Example

put_grid([
    [put_text('A'), put_text('B'), put_text('C')],
    [None, span(put_text('D'), col=2, row=1)],
    [put_text('E'), put_text('F'), put_text('G')],
], cell_width='100px', cell_height='100px')
pywebio.output.style(outputs, css_style)Union[pywebio.io_ctrl.Output, pywebio.io_ctrl.OutputList][源代码]

自定义输出内容的css样式

参数
  • outputs (list/put_xxx()) – 输出内容,可以为 put_xxx() 调用或其列表。outputs为列表时将为每个列表项都添加自定义的css样式。

  • css_style – css样式字符串

返回

添加了css样式的输出内容。

outputsput_xxx() 调用,返回值为添加了css样式的输出, 可用于任何接受 put_xxx() 类调用的地方。
outputs 为list,返回值为 outputs 中每一项都添加了css样式的list, 可用于任何接受 put_xxx() 列表的地方。

Example

style(put_text('Red'), 'color:red')

style([
    put_text('Red'),
    put_markdown('~~del~~')
], 'color:red')

put_table([
    ['A', 'B'],
    ['C', style(put_text('Red'), 'color:red')],
])

put_collapse('title', style([
    put_text('text'),
    put_markdown('~~del~~'),
], 'margin-left:20px'))

其他

pywebio.output.output(*contents)[源代码]

返回一个handler,相当于 put_xxx() 的占位符,可以传入任何接收 put_xxx() 调用的地方,通过handler可对自身内容进行修改

output用于对 组合输出 中的 put_xxx() 子项进行动态修改(见下方代码示例)

参数

contents – 要输出的初始内容. 元素为 put_xxx() 形式的调用或字符串,字符串会被看成HTML.

返回

OutputHandler 实例, 实例支持的方法如下:

  • reset(*contents) : 重置内容为 contents

  • append(*contents) : 在末尾追加内容

  • insert(idx, *contents) : 插入内容. idx 表示内容插入位置:

    idx>=0 时表示输出内容到原内容的idx索引的元素的前面;
    idx<0 时表示输出内容到到原内容的idx索引元素之后.
Example

hobby = output(put_text('Coding'))
put_table([
   ['Name', 'Hobbies'],
   ['Wang', hobby]      # hobby 初始为 Coding
])

hobby.reset(put_text('Movie'))  # hobby 被重置为 Movie
hobby.append(put_text('Music'), put_text('Drama'))   # 向 hobby 追加 Music, Drama
hobby.insert(0, put_markdown('**Coding**'))  # 将 Coding 插入 hobby 顶端