Python和Smalltalk-元编程功能比较

Python和Smalltalk-元编程功能比较,python,oop,programming-languages,metaprogramming,smalltalk,Python,Oop,Programming Languages,Metaprogramming,Smalltalk,我最近一直在学习Python,并对其出色的运行时元编程功能感到惊讶。之前,我在阅读Smalltalk时遇到了术语“运行时元编程”,据我所知,Smalltalk拥有最佳的运行时元编程功能。Python与Smalltalk w.r.t.元编程相比有多好?这两种语言所采用的方法之间有什么显著的区别?Python实际上在这里表现得相当不错。Smalltalk通常不明确区分程序和元程序,但Python更为明确-例如,装饰程序的特殊语法或元编程挂钩的命名约定。这是一件好事 另一方面,这有点像苹果对橙子的比较

我最近一直在学习Python,并对其出色的运行时元编程功能感到惊讶。之前,我在阅读Smalltalk时遇到了术语“运行时元编程”,据我所知,Smalltalk拥有最佳的运行时元编程功能。Python与Smalltalk w.r.t.元编程相比有多好?这两种语言所采用的方法之间有什么显著的区别?

Python实际上在这里表现得相当不错。Smalltalk通常不明确区分程序和元程序,但Python更为明确-例如,装饰程序的特殊语法或元编程挂钩的命名约定。这是一件好事

另一方面,这有点像苹果对橙子的比较。Smalltalk是一种比Python更小、更紧凑的语言,因此使用元程序操作的材料更少。例如,考虑<代码>这是一个钩子,允许Python对象提供属性访问的自定义实现。Smalltalk没有这样的东西。但是Smalltalk强制对对象的内部状态进行更严格的封装,并且没有Python中使用的
object.attribute
语法。所以读取一个对象的状态需要通过一个方法。。。这正是
\uuu getattr\uuuu()
所提供的。因此,对于在Python中使用
\uuu getattr\uuu()
的许多情况,您只需在Smalltalk中编写一个普通的方法,无需元编程

到处都是这样的:Python的
\uu getitem\uu()
和friends使得编写模仿列表或字典的类成为可能。Smalltalk不需要这些,因为Array和Dictionary只是普通的Smalltalk类,并且没有使用它们的特殊语法。Python
\uuuu eq\uuuu()
等启用运算符重载。Smalltalk没有运算符,因此您可以实现
+
,而无需执行任何特殊操作。Python的contextlib提供了一些漂亮的工具来实现您自己的上下文管理器。Smalltalk没有带结构的
,但它确实为lambdas提供了轻量级语法,让您能够以简单的方式完成同样的事情

Smalltalk的元编程工具往往非常低级。例如,您可以创建自己的
CompiledMethod
实例,并将它们粘贴到类的方法字典中。您还可以编写自己的编译器,并指定使用它编译特定类的所有方法。这就实现了各种各样的功能——我见过一些项目在实验中使用了交替语法、用于分析的工具字节码、用于透明持久性的陷阱读写实例变量,等等


Smalltalk的元编程工具功能强大,但它们的组织不如Python的那么整齐,而且使用频率也不高。

应提问者的要求作为答案发布


Smalltalk的一个重要思想是正交性。坦率地说,Python在这方面受到了影响。不是每件事都对每件事有效。示例:

  • inspect.getargspec()
    对内置函数或调用
    functools.partial的结果不起作用(无论如何在C解释器中)
  • eval
    仅适用于表达式字符串,
    exec
    仅适用于语句字符串
  • Lambda表达式不能被pickle
  • myclass=type('x',(object,),{uuuuu init\uuuuuu':partial(foo,value)}
    生成一个无法实例化的类,而传递一个等价的
    lambda
    表达式而不是
    partial
    可以很好地工作。(尽管这可能只是一个bug,而不是一个特性。)

也许派比没有这些问题,我不确定。但是我非常喜欢Python,并且发现在实际应用程序中使用元类、curry和偶尔使用的描述符非常方便。

在Python中,类型和可调用项是第一流的,编写它们,甚至在运行时创建它们是合理的。任何比这更神奇的东西通常被认为是非“蟒蛇式的”。我们不喜欢用python创建DSL,我们只使用python。@谢谢您的回复!我的问题不是元编程是否是python的,或者是否应该这样做。这是一个关于两种语言元编程能力比较研究的简单学术问题。Smalltalk的一个重要思想是正交性。坦率地说,Python在这方面受到了影响。不是每件事都对每件事有效。示例:inspect.getargspec()不适用于内置函数(无论如何在C解释器中)。eval仅适用于表达式字符串,exec仅适用于语句字符串。Lambda表达式不能被pickle。也许派比没有这些问题,我不确定。但我确实非常喜欢Python,并且发现在实际应用程序中使用元类、curry和偶尔使用的描述符非常方便。你可以把它作为一个答案发布出来。C和Python函数之间的许多差异确实在PyPy中被消除了(你不能通过行为来真正区分它们)。酸洗限制仍然存在(仅仅因为酸洗是疯狂的)@fijal:酸洗有什么疯狂之处?酸洗依赖于全局状态按名称引用所有函数和类。请参阅NamedTupleCrazyS.\u getframe hacks以解决此问题为例。在全局名称空间中不能通过名称引用lambda,因此不能对它们进行pickle(这就是它的设计方式,在PyPy中也是如此),所以pickle不是真的疯狂,更像是谎言?如果在一个VM中取消勾选,其中相同的名称表示不同的内容,那么取消勾选仍然可以(取决于)起作用,但是您得到的对象与放入的对象不同?