我有一组对象,我正在创建一个类,我想将每个对象存储为自己的文本文件。我真的很想将它存储为 Python 类定义,它对我正在创建的主类进行子类化。所以,我做了一些探索,并在 effbot.org 上找到了一个 Python Code Generator。我做了一些实验,这里是我想出的:
#
# 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')
这感觉真的很难看,有一个更清洁 / 更好 / 更多的 Python 的方式来做到这一点?请注意,这不是我真正打算这样做的类,这是一个小类,我可以很容易地模拟在没有太多的行。此外,子类不需要在其中有生成函数,如果我再次需要,我可以从超类调用代码生成器。
我们使用 Jinja2 来填充一个模板。
该模板看起来很像 Python 代码,其中有一些{{something}}
替换。
只需阅读您对 Wintermute 的评论-即:
我所拥有的是一堆行星,我想将它们存储为自己的文本文件。
如果是这样的话,那么似乎你不应该需要子类,但应该能够使用同一个类,并通过数据单独区分行星。在这种情况下,为什么不只是将数据写入文件,当你需要程序中的行星对象时,读入数据来初始化对象?
如果你需要做的东西,如重写方法,我可以看到写出来的代码-但你不应该只是能够有所有的行星相同的方法,只是使用不同的变量?
只写数据的优点(它可以包括标签类型信息的可读性,你会跳过,当你读它)是,非 Python 程序员不会分心阅读时,你可以使用相同的文件与一些其他语言,如果有必要,等等。
我不知道这是否是特别的 Pythonic,但你可以使用运算符重载:
class CodeGenerator:
def __init__(self, indentation='\t'):
self.indentation = indentation
self.level = 0
self.code = ''
def indent(self):
self.level += 1
def dedent(self):
if self.level > 0:
self.level -= 1
def __add__(self, value):
temp = CodeGenerator(indentation=self.indentation)
temp.level = self.level
temp.code = str(self) + ''.join([self.indentation for i in range(0, self.level)]) + str(value)
return temp
def __str__(self):
return str(self.code)
a = CodeGenerator()
a += 'for a in range(1, 3):\n'
a.indent()
a += 'for b in range(4, 6):\n'
a.indent()
a += 'print(a * b)\n'
a.dedent()
a += '# pointless comment\n'
print(a)
当然,这比你的例子要昂贵得多,我会警惕太多的元编程,但这是一个有趣的练习。
添加写入方法并将 stdout 重定向到此对象以直接打印到脚本文件
从它继承以自定义输出
添加属性 getter 和 setter
很高兴听到你的任何消息:)
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(63条)