mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-07-28 08:41:29 +00:00
📝 Docs: 更新最佳实践的 Alconna 部分 (#2443)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: StarHeartHunt <starheart233@gmail.com>
This commit is contained in:
@ -6,9 +6,9 @@ description: Alconna 基本介绍
|
||||
# Alconna 命令解析
|
||||
|
||||
[Alconna](https://github.com/ArcletProject/Alconna) 作为命令解析器,
|
||||
是一个简单、灵活、高效的命令参数解析器, 并且不局限于解析命令式字符串。
|
||||
是一个简单、灵活、高效的命令参数解析器,并且不局限于解析命令式字符串。
|
||||
|
||||
特点包括:
|
||||
特点包括:
|
||||
|
||||
- 高效
|
||||
- 直观的命令组件创建方式
|
||||
@ -16,10 +16,94 @@ description: Alconna 基本介绍
|
||||
- 自定义的帮助信息格式
|
||||
- 多语言支持
|
||||
- 易用的快捷命令创建与使用
|
||||
- 可创建命令补全会话, 以实现多轮连续的补全提示
|
||||
- 可创建命令补全会话,以实现多轮连续的补全提示
|
||||
- 可嵌套的多级子命令
|
||||
- 正则匹配支持
|
||||
|
||||
## 命令示范
|
||||
|
||||
```python
|
||||
import sys
|
||||
from io import StringIO
|
||||
|
||||
from arclet.alconna import Alconna, Args, Field, Option, CommandMeta, MultiVar, Arparma
|
||||
from nepattern import AnyString
|
||||
|
||||
alc = Alconna(
|
||||
"exec",
|
||||
Args["code", MultiVar(AnyString), Field(completion=lambda: "print(1+1)")] / "\n",
|
||||
Option("纯文本"),
|
||||
Option("无输出"),
|
||||
Option("目标", Args["name", str, "res"]),
|
||||
meta=CommandMeta("exec python code", example="exec\\nprint(1+1)"),
|
||||
)
|
||||
|
||||
alc.shortcut(
|
||||
"echo",
|
||||
{"command": "exec 纯文本\nprint(\\'{*}\\')"},
|
||||
)
|
||||
|
||||
alc.shortcut(
|
||||
"sin(\d+)",
|
||||
{"command": "exec 纯文本\nimport math\nprint(math.sin({0}*math.pi/180))"},
|
||||
)
|
||||
|
||||
|
||||
def exec_code(result: Arparma):
|
||||
if result.find("纯文本"):
|
||||
codes = list(result.code)
|
||||
else:
|
||||
codes = str(result.origin).split("\n")[1:]
|
||||
output = result.query[str]("目标.name", "res")
|
||||
if not codes:
|
||||
return ""
|
||||
lcs = {}
|
||||
_stdout = StringIO()
|
||||
_to = sys.stdout
|
||||
sys.stdout = _stdout
|
||||
try:
|
||||
exec(
|
||||
"def rc(__out: str):\n "
|
||||
+ " ".join(_code + "\n" for _code in codes)
|
||||
+ " return locals().get(__out)",
|
||||
{**globals(), **locals()},
|
||||
lcs,
|
||||
)
|
||||
code_res = lcs["rc"](output)
|
||||
sys.stdout = _to
|
||||
if result.find("无输出"):
|
||||
return ""
|
||||
if code_res is not None:
|
||||
return f"{output}: {code_res}"
|
||||
_out = _stdout.getvalue()
|
||||
return f"输出: {_out}"
|
||||
except Exception as e:
|
||||
sys.stdout = _to
|
||||
return str(e)
|
||||
finally:
|
||||
sys.stdout = _to
|
||||
|
||||
print(exec_code(alc.parse("echo 1234")))
|
||||
print(exec_code(alc.parse("sin30")))
|
||||
print(
|
||||
exec_code(
|
||||
alc.parse(
|
||||
"""\
|
||||
exec
|
||||
print(
|
||||
exec_code(
|
||||
alc.parse(
|
||||
"exec\\n"
|
||||
"import sys;print(sys.version)"
|
||||
)
|
||||
)
|
||||
)
|
||||
"""
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## 命令编写
|
||||
|
||||
### 命令头
|
||||
@ -115,7 +199,7 @@ alc = Alconna(
|
||||
- `help_text`: 传入该组件的帮助信息
|
||||
- `dest`: 被指定为解析完成时标注匹配结果的标识符,不传入时默认为选项或子命令的名称 (name)
|
||||
- `requires`: 一段指定顺序的字符串列表,作为唯一的前置序列与命令嵌套替换
|
||||
对于命令 `test foo bar baz qux <a:int>` 来讲,因为`foo bar baz` 仅需要判断是否相等, 所以可以这么编写:
|
||||
对于命令 `test foo bar baz qux <a:int>` 来讲,因为`foo bar baz` 仅需要判断是否相等,所以可以这么编写:
|
||||
|
||||
```python
|
||||
Alconna("test", Option("qux", Args["a", int], requires=["foo", "bar", "baz"]))
|
||||
@ -263,7 +347,7 @@ args = Args["foo", BasePattern("@\d+")]
|
||||
|
||||
### 紧凑命令
|
||||
|
||||
`Alconna`, `Option` 与 `Subcommand` 可以设置 `compact=True` 使得解析命令时允许名称与后随参数之间没有分隔:
|
||||
`Alconna`,`Option` 可以设置 `compact=True` 使得解析命令时允许名称与后随参数之间没有分隔:
|
||||
|
||||
```python
|
||||
from arclet.alconna import Alconna, Option, CommandMeta, Args
|
||||
@ -390,14 +474,14 @@ class ShortcutArgs(TypedDict):
|
||||
|
||||
- `{%X}`: 如 `setu {%0}`,表示此处必须填入快捷指令后随的第 X 个参数。
|
||||
|
||||
例如,若快捷指令为 `涩图`, 配置为 `{"command": "setu {%0}"}`, 则指令 `涩图 1` 相当于 `setu 1`
|
||||
例如,若快捷指令为 `涩图`,配置为 `{"command": "setu {%0}"}`,则指令 `涩图 1` 相当于 `setu 1`
|
||||
|
||||
- `{*}`: 表示此处填入所有后随参数,并且可以通过 `{*X}` 的方式指定组合参数之间的分隔符。
|
||||
- `{X}`: 表示此处填入可能的正则匹配的组:
|
||||
- 若 `command` 中存在匹配组 `(xxx)`,则 `{X}` 表示第 X 个匹配组的内容
|
||||
- 若 `command` 中存储匹配组 `(?P<xxx>...)`, 则 `{X}` 表示名字为 X 的匹配结果
|
||||
- 若 `command` 中存储匹配组 `(?P<xxx>...)`,则 `{X}` 表示名字为 X 的匹配结果
|
||||
|
||||
除此之外, 通过内置选项 `--shortcut` 可以动态操作快捷指令。
|
||||
除此之外,通过内置选项 `--shortcut` 可以动态操作快捷指令。
|
||||
|
||||
例如:
|
||||
|
||||
@ -444,17 +528,17 @@ alc.parse("test_fuzy")
|
||||
|
||||
`path` 支持如下:
|
||||
|
||||
- `main_args`, `options`, ...: 返回对应的属性
|
||||
- `main_args`,`options`,...: 返回对应的属性
|
||||
- `args`: 返回 all_matched_args
|
||||
- `main_args.xxx`, `options.xxx`, ...: 返回字典中 `xxx`键对应的值
|
||||
- `main_args.xxx`,`options.xxx`,...: 返回字典中 `xxx`键对应的值
|
||||
- `args.xxx`: 返回 all_matched_args 中 `xxx`键对应的值
|
||||
- `options.foo`, `foo`: 返回选项 `foo` 的解析结果 (OptionResult)
|
||||
- `options.foo.value`, `foo.value`: 返回选项 `foo` 的解析值
|
||||
- `options.foo.args`, `foo.args`: 返回选项 `foo` 的解析参数字典
|
||||
- `options.foo.args.bar`, `foo.bar`: 返回选项 `foo` 的参数字典中 `bar` 键对应的值
|
||||
- `options.foo`,`foo`: 返回选项 `foo` 的解析结果 (OptionResult)
|
||||
- `options.foo.value`,`foo.value`: 返回选项 `foo` 的解析值
|
||||
- `options.foo.args`,`foo.args`: 返回选项 `foo` 的解析参数字典
|
||||
- `options.foo.args.bar`,`foo.bar`: 返回选项 `foo` 的参数字典中 `bar` 键对应的值
|
||||
...
|
||||
|
||||
同样, `Arparma["foo.bar"]` 的表现与 `query()` 一致
|
||||
同样,`Arparma["foo.bar"]` 的表现与 `query()` 一致
|
||||
|
||||
## Duplication
|
||||
|
||||
|
Reference in New Issue
Block a user