我最近一直在学习Python,并且对其出色的运行时元编程功能感到惊讶。以前我遇到过“运行时元编程”这个术语,当时我正在阅读有关Smalltalk的内容,据我所知,Smalltalk拥有最佳的运行时元编程功能。 Python与Smalltalk w.r.t的对比情况如何?元编程?两种语言采用的方法之间有什么显着差异?
答案 0 :(得分:12)
Python在这里实际上相当不错。 Smalltalk通常不会明确区分程序和元程序,但Python更明确 - 例如,装饰器的特殊语法或元编程钩子的__foo__()
命名约定。这是一件好事。
另一方面,这是一个苹果与橘子的比较。 Smalltalk是一种比Python更小,更紧凑的语言,因此使用元程序操作的材料更少。例如,考虑__getattr__()
。这是一个钩子,允许Python对象提供属性访问的自定义实现。 Smalltalk没有这样的东西。但! Smalltalk强制对对象的内部状态进行更严格的封装,并且没有相当于Python中使用的object.attribute
语法。因此,读取对象的状态需要通过一个方法......这正是__getattr__()
提供的方法。因此,对于很多在Python中使用__getattr__()
的情况,你只需在Smalltalk中编写一个普通的方法 - 不需要元编程。
就像所有地方一样:Python的__getitem__()
和朋友可以编写模仿列表或词典的类。 Smalltalk不需要它,因为Array和Dictionary只是常规的Smalltalk类,并且没有使用它们的特殊语法。 Python __eq__()
等启用运算符重载。 Smalltalk没有运算符,因此您可以在不做任何特殊操作的情况下实现+
。 Python的contextlib提供了一些实现自己的上下文管理器的漂亮工具。 Smalltalk没有with
构造,但它确实具有lambdas的非常轻量级的语法,它允许您以直接的方式执行相同类型的操作。
Smalltalk的元编程设施往往很低级。例如,您可以创建自己的CompiledMethod
实例,并将它们粘贴到类的方法字典中。您也可以编写自己的编译器,并指定使用它编译特定类的所有方法。这可以实现各种各样的事情 - 我已经看到了用替代语法进行实验的项目,用于分析的工具字节码,用于透明持久性的陷阱读取和写入实例变量等等。
Smalltalk的元编程功能很强大,但它们不像Python那样整齐有序,并且不经常使用。
答案 1 :(得分:10)
根据提问者的要求发布答案。
Smalltalk的一个重要想法是正交性。坦率地说,Python在这方面受到了影响。并非一切都适用于一切。例子:
inspect.getargspec()
不适用于内置函数或调用functools.partial
的结果(无论如何都在C解释器中)。eval
仅适用于表达式字符串,exec
仅适用于语句字符串。myclass = type('x', (object,), {'__init__': partial(foo, value)})
生成一个无法实例化的类,而传递等效的lambda
表达式而不是partial
的工作正常。 (虽然这可能只是一个错误而不是一个功能。)也许PyPy没有这些问题,我不确定。但我非常喜欢Python,并且发现在实际应用程序中使用元类,currying和偶尔的描述符非常方便。