Hello! 欢迎来到小浪资源网!

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


背景

我目前正在开发一个基于 pyodideui 框架,称为 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免费学习笔记(深入)”;

相关阅读