针对.pyc文件的编译器?

3

好奇一下,有多少编译器能够将代码编译成 .pyc 文件?

经过一番搜索,我只找到了以下两种:

  • unholy: why_ 的 Ruby-to-pyc 编译器
  • Python: Python 转 pyc 的编译器

那么… 还有其他的吗?

(顺便说一句,我开始思考这个问题是因为我想写一个 Scheme-to-pyc 的编译器)

(再顺便说一句,我并没有幻想一个 Scheme-to-pyc 的编译器会有什么实际用途,但它可以给我一个学习 Scheme 和 Python 内部机制的绝佳借口)


2
我相当确定 unholy 只存在是因为 _why 很疯狂。(确切地说是疯狂得很棒。) - Bob Aman
1
如果您想生成在Python运行时执行的代码,远比直接生成Python字节码更好的方法是生成Python代码并编译它。 - Glenn Maynard
@Glenn同意 - 一个Scheme到Python的编译器会更加明智...但我不想在这里变得明智,我想学习Python的内部结构(以及实现Scheme所需的内容)。 - David Wolever
5个回答

4

我想写一个Scheme到pyc的编译器。

这让我感到头疼!你为什么要这样做呢?Python字节码是一种中间语言,专门设计满足Python语言的需要,并设计运行在Python虚拟机上,而这些虚拟机又是根据Python的需求进行了定制。目前Python开发中最重要的领域之一是将Python移植到其他“虚拟机”,例如Jython(JVM)、IronPython(.NET)、PyPyUnladen Swallow项目(将CPython移植到基于LLVM的表示形式)。试图将另一种非常不同的语言(Scheme)的语法和语义挤进另一种高级语言的中间表示似乎是在错误的层次上攻击问题(无论问题是什么)。因此,总的来说,似乎没有太多.py编译器存在的原因就在于这个。


为什么我想要这样做?有什么不喜欢的呢?!我可以学习Scheme和Python的内部结构(尽管在不同的层次上...但仍然可以)! - David Wolever
但更严肃的是,你提出了一个我没有考虑到的好观点:与一般字节码(.swf或.class?)不同,pyc仅设计用于适应Python...因此,将其作为目标并没有太多意义。 - David Wolever
至少,如果你的目标是生产出有用的东西,这样做是没有意义的 :P - David Wolever

3

几年前,我写了一个编译器,它接受一种类似于Lisp的语言称为“Noodle”,并生成Python字节码。虽然它从未变得特别有用,但对于更好地理解Common Lisp(我复制了其中的一些功能)和更好地理解Python来说,这是一次非常好的学习经验。

我可以想到两种情况,直接针对Python字节码可能会更有用,而不是生成Python并将其传递给Python编译器:

  1. Full closures: 在 Python 3.0 之前(在 nonlocal 关键字之前),你不能修改闭包变量的值,除非使用字节码技巧。你可以改变值而不是修改,因此通常习惯于引用一个列表的闭包,并从内部作用域中更改第一个元素。这可能会变得真的很烦人。限制是语法的一部分,而不是 Python VM。我的语言有明确的变量声明,因此成功地提供了可修改闭合值的“正常”闭包。
  2. 获取 traceback 对象而不引用任何内置对象。确实是一个小众案例,但我用它来打破早期版本的“safelite”监狱。请参见my posting

所以,是的,这可能比它值得的工作要多得多,但我很喜欢它,你也可能会喜欢。


感谢您的评论,保罗!我很高兴知道我不是疯了 :) 同时,欢迎来到 Stack Overflow。 - David Wolever

2

仅供参考,我已经编写了一个从简单的LISP到Python的玩具编译器。实际上,这是一个LISP到pyc的编译器。

看一下:sinC - 最小的LISP编译器


2
我建议你专注于CPython。

http://www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html

与其写一个 Scheme 到 .pyc 的转换器,我建议您编写一个 Scheme 到 Python 的翻译器,然后让 CPython 处理转换为 .pyc。(这样做有先例;第一个 C++ 编译器是 Cfront,它将 C++ 转换为 C,然后让系统的 C 编译器完成剩下的工作。)
从我对 Scheme 的了解来看,将 Scheme 翻译为 Python 并不难。
一个警告:对于 Scheme 来说,Python 虚拟机可能不如 Scheme 本身快。例如,Python 不会自动将尾递归转换为迭代;而且 Python 的堆栈相对较浅,因此您实际上需要将尾递归转换为迭代。
作为奖励,一旦 Unladen Swallow 加速 Python,您的 Scheme-to-Python 翻译器将受益,到那时甚至可能变得实用!
如果您觉得这是一个有趣的项目,我建议您去试试。并不是每个项目都必须立即实用。
附言:如果您想要一个更实用的项目,您可能需要编写一个 AWK 到 Python 的翻译器。这样,使用传统 AWK 脚本的人就可以轻松地跨越到 Python!

嗯,他的列表中已经有CPython了:那是PSF的Python到pyc编译器。 - Ned Deily
2
嗯...从Awk转到Python...这甚至更让人不爽...但是它确实有潜在的有用之处... - David Wolever
我建议这样做的主要原因是,我回答了一个关于如何从AWK文件制作独立二进制文件的问题。Python有几种方法可以制作独立的二进制文件(例如,对于Windows,Py2Exe:http://www.py2exe.org/)。如果你能将AWK转换为Python,那么你就可以制作一个独立的二进制文件! - steveha
@Ned Deily:你之所以这么说是因为它是真的...好吧,我会编辑我的答案。 - steveha

1

可能有点晚了,但如果您仍然感兴趣,clojure-py项目(https://github.com/halgari/clojure-py)现在能够将Clojure的大部分内容编译为Python字节码——但始终需要一些帮助。

本身针对字节码并不难,除了一个问题:它在不同平台上不稳定(例如,在Python 3中,MAKE_FUNCTION从堆栈中弹出2个元素,但在Python 2中只弹出1个),而这些差异没有在单个位置清晰地记录下来(据我所知)——因此可能需要一些抽象层。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接