CQL 教程/CQL 进阶/高级特性

高级特性

探索 CQL 的高级语法:lambda、装饰器、上下文管理器、生成器、异步与模式匹配。

17.1延迟 lambda

延迟 是 CQL 中的 lambda 关键字,可以定义匿名函数,也能与地图、过滤器等函数式内置函数结合。完整示例参考 examples/lambda_map.cql

cql
# lambda 匿名函数
翻倍 = 延迟 x: x * 2
打印("翻倍:", 翻倍(21))   # 42

# 与地图结合:逐元素映射
数字 = [1, 2, 3, 4, 5]
平方 = 列表(地图(延迟 x: x * x, 数字))
打印("平方:", 平方)       # [1, 4, 9, 16, 25]

# 与过滤器结合:按条件筛选
偶数 = 列表(过滤器(延迟 x: x % 2 == 0, 数字))
打印("偶数:", 偶数)       # [2, 4]

# 与排序结合:关键字参数 key
学生 = [("张三", 88), ("李四", 95), ("王五", 72)]
按分数排序 = 排序(学生, key=延迟 项目: 项目[1], reverse=True)
打印("按分数排序:", 按分数排序)

17.2装饰器

@装饰器名 装饰函数。下面的计时器示例来自 examples/decorator_timer.cql,演示了装饰器与 *args / **kwargs 的配合:

cql
# CQL 示例:装饰器(计时器)
导入 time

函数 计时器(func):
    函数 包装(*args, **kwargs):
        开始 = time.time()
        结果 = func(*args, **kwargs)
        结束 = time.time()
        打印("{} 耗时 {:.4f} 秒".format(func.__name__, 结束 - 开始))
        返回 结果
    返回 包装

@计时器
函数 求和到(n):
    总数 = 0
    循环 i 在 范围(n + 1):
        总数 += i
    返回 总数

打印("结果:", 求和到(1000000))
out
求和到 耗时 0.0500 秒
结果: 500000500000

装饰器也可以带参数,例如 @重复(3),其中 重复 返回一个装饰器再应用到函数上。

17.3伴随 with

伴随 是 CQL 中的 with 关键字,配合 打开 可以自动管理文件资源(退出块时自动关闭)。文件方法同样支持中文名:

cql
# 伴随 with 读写文件
伴随 打开("示例输出.txt", "w", encoding="utf-8") 作为 f:
    f.写入("第一行:CQL 文件写入\n")   # 等价于 f.write(...)
    f.写入("第二行:with 自动关闭文件\n")

伴随 打开("示例输出.txt", "r", encoding="utf-8") 作为 f:
    内容 = f.读取()                    # 等价于 f.read()

打印("文件内容:")
打印(内容)
打印("文件已自动关闭:", f.closed)

自定义上下文管理器通过 __enter____exit__ 两个方法实现,完整示例参考 examples/with_file.cql

cql
# 自定义上下文管理器
类 计时上下文:
    函数 __init__(自身, 名称):
        自身.名称 = 名称

    函数 __enter__(自身):
        自身.开始 = time.time()
        打印("进入:", 自身.名称)
        返回 自身

    函数 __exit__(自身, 异常类型, 异常值, 追踪):
        耗时 = time.time() - 自身.开始
        打印("退出:{},耗时 {:.4f} 秒".format(自身.名称, 耗时))
        返回 假

伴随 计时上下文("自定义上下文") 作为 上下文:
    总数 = 0
    循环 i 在 范围(100000):
        总数 += i
    打印("计算完成:", 总数)
提示:文件中文方法名双目标支持:读取(read 全部)、写入(write)、关闭(close)、读行(readline)、读全部行(readlines)、写行(writelines)、刷新(flush),f.closed 属性同样可用。

17.4生成器

在函数里使用 产量(yield)就把函数变成生成器,每次迭代返回一个值并暂停;产量 从 可以把子生成器的值委托出来。完整示例参考 examples/generator.cql

cql
# 产量:生成器
函数 斐波那契生成器(上限):
    a, b = 0, 1
    计数 = 0
    当 计数 < 上限:
        产量 a
        a, b = b, a + b
        计数 += 1

打印("斐波那契生成器:")
循环 值 在 斐波那契生成器(10):
    打印(值, end=" ")
打印()
cql
# 产量 从:委托给子生成器
函数 子生成器():
    产量 1
    产量 2

函数 主生成器():
    产量 0
    产量 从 子生成器()
    产量 3

打印("yield from 示例:", 列表(主生成器()))
# [0, 1, 2, 3]

# 生成器表达式
平方和 = 求和(x * x 循环 x 在 范围(10))
打印("1..9 的平方和:", 平方和)  # 285

17.5异步

CQL 使用 异步函数 定义协程、等待 挂起并等待异步结果,转译器分别编译为 Python 的 async defawait(JavaScript 目标为 async function / await,顶层等待自动包一层 async IIFE):

cql
# 异步函数 与 等待
异步函数 取数(x):
    返回 x * 2

类 计算器:
    异步函数 加倍(自身, x):
        返回 x + x

打印(等待 取数(21))        # 42
打印(等待 计算器().加倍(5))  # 10
python
# 编译产物(片段)
async def 取数(x):
    return x * 2

print(await 取数(21))
说明:早期文档(DEVELOPER_GUIDE)曾把 async/await 列为不支持的语法,但当前 README 的特性声明与测试用例均确认异步已支持(异步函数 / 等待 正确编译为 async def / await),请以 README 的写法为准。

17.6匹配 与 情况

匹配 / 情况 对应 Python 3.10+ 的 match / case 模式匹配,支持字面量、或模式、序列解包、字典映射、守卫与通配符:

cql
# 匹配 与 情况(模式匹配)
函数 描述(值):
    匹配 值:
        情况 1:
            返回 "一"
        情况 2 | 3:
            返回 "二或三"
        情况 [x, y]:
            返回 "两个:" + 文本(x) + "," + 文本(y)
        情况 {"类型": "狗", "名字": n}:
            返回 "狗:" + n
        情况 n 如果 n > 100:
            返回 "大数:" + 文本(n)
        情况 _:
            返回 "其他"

打印(描述(1))                          # 一
打印(描述(3))                          # 二或三
打印(描述([7, 8]))                     # 两个:7,8
打印(描述({"类型": "狗", "名字": "旺财"}))  # 狗:旺财
打印(描述(250))                        # 大数:250
打印(描述(-1))                         # 其他
提示:守卫条件(情况 n 如果 n > 100)失败时不会中断,会继续尝试后面的情况分支,与 Python 的 match 语义一致。