Python生成Python

Jon*_*anb 16 python code-generation

我有一组对象,我正在创建一个类,我想将每个对象存储为自己的文本文件.我真的想将它存储为Python类定义,它定义了我正在创建的主类.所以,我做了一些讨论,并在effbot.org上找到了一个Python代码生成器.我做了一些实验,这就是我想出来的:

#
# a Python code generator backend
#
# fredrik lundh, march 1998
#
# fredrik@pythonware.com
# http://www.pythonware.com
#
# Code taken from http://effbot.org/zone/python-code-generator.htm

import sys, string

class CodeGeneratorBackend:

    def begin(self, tab="\t"):
        self.code = []
        self.tab = tab
        self.level = 0

    def end(self):
        return string.join(self.code, "")

    def write(self, string):
        self.code.append(self.tab * self.level + string)

    def indent(self):
        self.level = self.level + 1

    def dedent(self):
        if self.level == 0:
            raise SyntaxError, "internal error in code generator"
        self.level = self.level - 1

class Point():
    """Defines a Point. Has x and y."""
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def dump_self(self, filename):
        self.c = CodeGeneratorBackend()
        self.c.begin(tab="    ")
        self.c.write("class {0}{1}Point()\n".format(self.x,self.y))
        self.c.indent()
        self.c.write('"""Defines a Point. Has x and y"""\n')
        self.c.write('def __init__(self, x={0}, y={1}):\n'.format(self.x, self.y))
        self.c.indent()
        self.c.write('self.x = {0}\n'.format(self.x))
        self.c.write('self.y = {0}\n'.format(self.y))
        self.c.dedent()
        self.c.dedent()
        f = open(filename,'w')
        f.write(self.c.end())
        f.close()

if __name__ == "__main__":
    p = Point(3,4)
    p.dump_self('demo.py')
Run Code Online (Sandbox Code Playgroud)

感觉非常难看,是否有更清洁/更好/更pythonic的方式来做到这一点?请注意,这不是我实际打算用它做的类,这是一个很小的类,我可以轻松地在很多行中进行模拟.此外,子类不需要在其中具有生成函数,如果我再次需要它,我可以从超类调用代码生成器.

S.L*_*ott 28

我们使用Jinja2填写模板.它简单得多.

该模板看起来很像Python代码,其中包含一些{{something}}替代品.

  • 这是一个例子吗? (3认同)

Ano*_*non 7

只需阅读您对wintermute的评论 - 即:

我所拥有的是一堆行星,我想将每个行星存储为自己的文本文件.我并不特别喜欢将它们存储为python源代码,但我很依赖它们使它们具有人类可读性.

如果是这种情况,那么您似乎不应该需要子类,但应该能够使用相同的类并仅通过数据来区分行星.在这种情况下,为什么不将数据写入文件,当您需要程序中的行星对象时,读入数据来初始化对象?

如果你需要做一些像重写方法的东西,我可以看到写出代码 - 但是你不应该只为所有行星使用相同的方法,只使用不同的变量吗?

只写出数据的优点(它可以包括标签类型信息以便在读取时跳过),非Python程序员在阅读时不会分心,你可以使用相同的文件必要时使用其他语言等

  • 是的,我对这个问题想得有点太深了,不是吗。这很可能是我会做的。谢谢你! (2认同)

Gre*_*ill 5

这几乎是生成Python 代码的最佳方式.但是,您也可以使用ast库在运行时生成Python可执行代码.(我链接到Python 3版本,因为它比2.x版本更强大.)您可以使用抽象语法树构建代码,然后将其传递给compile()可编译代码.然后您可以eval用来运行代码.

我不确定是否有一种方便的方法来保存编译后的代码以供以后使用(即在.pyc文件中).

  • 在 Python 3.9+ 中,有 [`ast.unparse()`](https://docs.python.org/3.9/library/ast.html#ast.unparse) (2认同)