Python 宏:用例?
如果Python有一个像Lisp/Scheme那样的宏功能(类似于MetaPython),你会怎么使用它呢?
如果你是Lisp/Scheme的程序员,你通常会用宏来做些什么(除了那些在Python中有明显语法对应的东西,比如while循环)?
16 个回答
14
我认为宏与Python的文化是相悖的。在Lisp语言中,宏可以让你以一种“大杂烩”的方式来处理问题;你可以重新定义语言,使其更适合你的问题领域。相反,Python的代码则是利用Python内置的最自然的特性来解决问题,而不是用其他语言中更自然的方式来解决。
宏本质上是不符合Python风格的。
16
这是一个稍晚的回答,不过我最近在做一个叫MacroPy的新项目,目的是把宏的功能带到Python中。我们有很多示例,都是需要用到宏才能实现的用例,比如提供一种非常简洁的方式来声明类:
@case
class Point(x, y)
p = Point(1, 2)
print p.x # 1
print p # Point(1, 2)
MacroPy已经被用来实现一些功能,比如:
- 案例类,这是一种来自Scala的简单代数数据类型
- 来自函数式编程世界的模式匹配
- 尾调用优化
- 准引号,这是一种快速操作程序片段的方法
- 字符串插值,这在很多语言中都是常见的特性,还有Pyxl
- 追踪和智能断言
- PINQ到SQLAlchemy,这是C#中的LINQ到SQL的克隆
- 来自Scala和Groovy的快速Lambda表达式
- 解析器组合器,灵感来自于Scala。
想了解更多信息,可以查看链接的页面;我可以自信地说,我们展示的用例远远超过了这个讨论串中任何人提出的建议 =D
11
以下是一些Lisp宏的例子:
- ITERATE,这是一个有趣且可扩展的循环工具。
- CL-YACC/FUCC,这些是解析器生成器,可以在编译时生成解析器。
- CL-WHO,这个工具可以让你指定包含静态和动态部分的HTML文档。
- Parenscript,这是一个生成JavaScript代码的工具。
- 各种简单的代码包装器,比如错误处理器(我有一个叫做with-gtk-error-message-handler的宏,它会执行代码并在发生未处理错误时显示GtkMessageDialog),执行器(例如,给定一段代码,在不同的线程中执行它;我有一个叫做within-main-thread的宏,可以在不同线程中执行代码;PCall库使用宏来包装代码,以便并发执行)。
- 使用宏的图形用户界面(GUI)构建器(例如,指定小部件的层次结构和属性,然后让宏生成创建所有小部件的代码)。
- 在编译时使用外部资源的代码生成器。例如,一个宏可以处理C语言的头文件并生成外部函数接口(FFI)代码,或者一个宏可以根据数据库模式生成类定义。
- 声明式外部函数接口(FFI)。例如,指定外部结构、函数及其参数类型,并使用宏生成相应的Lisp结构、函数以及类型映射和数据转换代码。
- 基于继续传递风格(CPS)的Web框架,使用宏将代码转换为CPS形式。