php中文网

Python 中的这种运行时元编程模式很有趣

php中文网

背景

我目前正在开发一个基于 pyodide 的 ui 框架,称为 zenaura。最近,我注意到构建器界面(用户创建 ui 元素的主要方式)有点过于复杂且没有吸引力。虽然它确实抽象了底层的、更麻烦的接口来与 zenaura 的虚拟 dom“节点”数据结构交互,但它仍然不能令人满意。我想简化事情并为用户提供更清晰、更直观的体验,同时为可能开发全新语法的编译器奠定基础。像这样的东西:

div(attr1=val1, child1, child2, child3)

问题陈述

当前的构建器界面太低级且用户不友好。用户不应该与这样的东西进行交互:

builder = builder(name__)
if children:
    builder.with_children(*children)
if attributes:
    builder.with_attributes(**attributes)
if text:
    builder.with_text(text)
# print("data", builder.node.children, builder.node.attributes)
return builder.build()

相反,他们应该能够使用更清晰、更易读的语法,例如:

div(id="some-id", h1("text"), p("text"))

查看 mdn 文档,有 91 个 html 标签,可能会添加或弃用。我最初考虑动态生成代码来简化此过程,但虽然它有效,但它不是最实用的解决方案。主要目标是在用户调用函数时显示文档字符串,但动态生成的方法引入了一些挑战,例如缺乏自动完成功能。

动态方法

这是我尝试过的动态生成的代码:

tag_config = {
    # root elements
    "html": "nestable",
    "main": "nestable",
    "body": "nestable",
}

tags_factory = {
    "nestable": lambda name__: f"""
{name__} = partial(nestable, "{name__}")
{name__}.__doc__ = nestable.__doc__
""",
    "textable": lambda name__: f"""
{name__} = partial(textable, "{name__}")
""",
    "self_closing": lambda name__: f"""
{name__} = partial(self_closing, "{name__}")
""",
    "nestable_no_attrs": lambda name__: f"""
{name__} = partial(nestable_no_attrs, "{name__}")
"""
}

for k, v in tag_config.items():
    exec(tags_factory[v](k), globals())

这在功能方面表现良好,但在可用性方面存在不足。主要缺点是缺乏自动完成功能,因为代码是在运行时注入的。然而,html 标签本身相对简单,因此目前还不是一个问题。

优点和局限性

这种方法的显着优势之一是灵活性。在 zenaura 中支持或弃用 html 元素就像在 tag_config 字典中添加或删除键值对一样简单。这是一种适应 html 标签随时间变化的简单方法。

此外,唯一的限制是自动完成和向用户显示文档字符串,我认为这是一个可以做出的权衡,因为 html 元素非常基本。

但是,权衡是以可用性的形式出现的:如果没有自动完成功能,用户在与界面交互时可能会面临挑战。也就是说,我相信这是尝试在 zenaura 中处理标签元素的新方法的一个很好的起点。

立即学习“Python免费学习笔记(深入)”;

以上就是Python 中的这种运行时元编程模式很有趣的详细内容,更多请关注php中文网其它相关文章!

上一篇:PSP 上的 Wasm TinyGo

下一篇:返回列表