有没有办法以编程方式生成Python字节码?

发布于 2024-08-06 11:30:40 字数 279 浏览 5 评论 0原文

我想使用 Python 解释器并尝试创建一个小型 DSL 。是否有任何模块可以让我执行类似理论代码的操作(类似于 LINQ 表达式树)?

expression_tree = Function(
    Print(
        String('Hello world!')
    )
 )
compile_to_bytecode(expression_tree)

或者生成 Python 源代码会更容易吗?使用 C 或 SWIG 或 Cython 可以让这变得更容易吗?

I want to hack around with the Python interpreter and try creating a small DSL . Is there any module where I can do something like this theoretical code (similar to LINQ expression trees)?

expression_tree = Function(
    Print(
        String('Hello world!')
    )
 )
compile_to_bytecode(expression_tree)

Or would it just be easier to just generate Python source code? Could this be made easier by using C or SWIG or Cython?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

小傻瓜 2024-08-13 11:30:40

正如另一个答案所暗示的那样,通过ast工作并将树编译成字节码可能是最简单的;生成源代码并编译它们,几乎一样好。

但是,要探索较低级别的方法,请查看此页面中的链接;我发现 byteplay 特别有用(目前不适用于 2.6 或 3.*,只有 2.4 或 2.5,但我认为将其修复为 2.6 应该很容易,正如目前在其跟踪器中讨论的那样)。我没有使用 Phil Eby 的类似功能 BytecodeAssembler,但考虑到作者的声誉,我确信它是值得一看!

Working via ast and compiling the tree into bytecode, as another answer suggests, is probably simplest; generating sources and compiling those, almost as good.

However, to explore lower-level approaches, check out the links from this page; I've found byteplay especially useful (currently doesn't work on 2.6 nor 3.*, only 2.4 or 2.5, but I think fixing it for 2.6 should be easy, as currently discussed in its tracker). I have not used Phil Eby's similarly-featured BytecodeAssembler, but given the author's reputation I'm sure it's worth checking it out!

仙女山的月亮 2024-08-13 11:30:40

在 Python 2.X 中,您通常会使用 编译器 module 及其 ast 子模块(但请注意,此模块自 2.6 版起已弃用)。在 Python 3.X 中,您只需使用 ast

两者都提供了一个compile()函数,该函数将从源代码/AST转换为“可以通过exec语句或eval()执行的代码对象”代码>。”

In Python 2.X, you would typically approach this with the compiler module and its ast sub-module (but note this module is deprecated since version 2.6). In Python 3.X, you would use just ast.

Both offer a compile() function that will go from source/AST to "a code object that can be executed by the exec statement or eval()."

长伴 2024-08-13 11:30:40

生成 Python 代码并运行它更容易。如果这样做,您还可以更轻松地调试它,因为调试器可以显示实际的源代码。另请参阅 Python 杂志七月号上的 Malte Borchs 文章,其中他讨论了这一点以及其他内容。

It's easier to generate Python code and run it. If you do that you can also debug it more easily since there is actual source for the debugger to display. See also Malte Borchs article in the July issue of Python magazine, where he talks about this amongst other things.

岁月蹉跎了容颜 2024-08-13 11:30:40

Fernando Meyer 最近写了一篇博文,解释如何使用 # 编码 指令指定您自己的 Python 扩展。示例(实际格式定义位于 pyspec.pytokenizer.py):

# coding: pyspec

class Bow:
    def shot(self):
        print "got shot"

    def score(self):
        return 5

describe Bowling:
    it "should score 0 for gutter game":
        bowling = Bow()
        bowling.shot()
        assert that bowling.score.should_be(5)

Fernando Meyer recently wrote a blog post explaining how to use the # coding directive to specify your own extensions to Python. Example (the actual format definition is in pyspec.py and tokenizer.py):

# coding: pyspec

class Bow:
    def shot(self):
        print "got shot"

    def score(self):
        return 5

describe Bowling:
    it "should score 0 for gutter game":
        bowling = Bow()
        bowling.shot()
        assert that bowling.score.should_be(5)
烛影斜 2024-08-13 11:30:40

更新 Python3 - 还有非常有趣的汇编器 zachariahreed/byteasm

实际上是 Py3 中唯一为我工作的。它有非常好的&干净的API:

>>> import byteasm, dis
>>> b = byteasm.FunctionBuilder()
>>> b.add_positional_arg('x')
>>> b.emit_load_const('Hello!')
>>> b.emit_load_fast('x')
>>> b.emit_build_tuple(2)
>>> b.emit_return_value()
>>> f = b.make('f')
>>> f
<function f at 0xb7012a4c>
>>> dis.dis(f)
  1           0 LOAD_CONST               0 ('Hello!')
              3 LOAD_FAST                0 (x)
              6 BUILD_TUPLE              2
              9 RETURN_VALUE
>>> f(108)
('Hello!', 108)

Updating for Python3 - there's also very interesting assembler zachariahreed/byteasm.

Actually the only one working for me in Py3. It has very nice & clean API:

>>> import byteasm, dis
>>> b = byteasm.FunctionBuilder()
>>> b.add_positional_arg('x')
>>> b.emit_load_const('Hello!')
>>> b.emit_load_fast('x')
>>> b.emit_build_tuple(2)
>>> b.emit_return_value()
>>> f = b.make('f')
>>> f
<function f at 0xb7012a4c>
>>> dis.dis(f)
  1           0 LOAD_CONST               0 ('Hello!')
              3 LOAD_FAST                0 (x)
              6 BUILD_TUPLE              2
              9 RETURN_VALUE
>>> f(108)
('Hello!', 108)
零度℉ 2024-08-13 11:30:40

查看此处找到的反汇编程序模块:

http://docs.python.org/library/dis。 html

Check out the disassembler module found here:

http://docs.python.org/library/dis.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文