从C#操作Python文件
我正在为我制作的游戏开发一些工具。这些工具的目的是让编辑游戏文件变得更简单。其中有几个文件是用Python编写的脚本文件。例如,我有一个叫Items.py的文件,里面包含了一些内容(为了举例,内容简化了)
from ItemModule import *
import copy
class ScriptedItem(Item):
def __init__(self, name, description, itemtypes, primarytype, flags, usability, value, throwpower):
Item.__init__(self, name, description, itemtypes, primarytype, flags, usability, value, throwpower, Item.GetNextItemID())
def Clone(self):
return copy.deepcopy(self)
ItemLibrary.AddItem(ScriptedItem("Abounding Crystal", "A colourful crystal composed of many smaller crystals. It gives off a warm glow.", ItemType.SynthesisMaterial, ItemType.SynthesisMaterial, 0, ItemUsage.Unusable, 0, 50))
正如我提到的,我想提供一个界面,让人们可以编辑这个文件,而不需要编辑者懂Python或直接修改文件。我的编辑器需要能够:
- 找到并列出所有的类类型(在这个例子中,只有 Scripted Item)
- 找到并列出所有创建的物品(在这个例子中只有一个, Abounding Crystal)。我需要找到物品的类型(在这个例子中是ScriptedItem)和所有的参数值
- 允许编辑参数,以及创建或删除物品。
为了实现这个目标,我开始编写自己的解析器,寻找类关键字,以及这些记录的类是如何用来构造对象的。对于简单的数据,这个方法有效,但当我开始使用带有复杂构造函数的类(比如列表、字典等)时,解析变得越来越困难。
经过一番搜索,我发现IronPython可以很方便地解析Python文件,于是我就开始使用它。一旦我构建了抽象语法树(AST),我就用PythonWalkers来识别和找到我需要的所有信息。这在读取数据时效果很好,但我找不到简单的方法将更新的数据写回Python文件。根据我的理解,似乎没有办法改变AST中的值,更不用说将AST转换回脚本文件。如果我错了,希望有人能告诉我该怎么做。现在我需要做的是在文件中搜索,直到找到正确的行,然后尝试将数据推送到构造函数中,确保顺序正确。
有没有什么明显的解决方案我没有想到?我应该继续完善我的解析器,让它支持更复杂的数据类型吗?我真的以为我在IronPython解析器上找到了办法,但没想到将修改后的数据推回文件会这么棘手。
任何建议都将不胜感激
4 个回答
如果你能找到一个完整且最新的Python上下文无关文法文件,你可以使用CoCo/R这个工具来生成一个用C#写的Python解析器。
你可以在文法文件里添加一些代码,这样就可以在你的C#应用程序中填充一个数据结构。这个数据结构可以存储你需要的所有信息,比如方法及其参数、属性、构造函数、析构函数等等。一旦你有了这个数据结构,接下来就是设计一个用户界面,让用户能够以一种可编辑的方式查看和修改这个数据结构(这其实更多是设计方面的工作,而不是复杂的编程任务)。
最后,遍历你的数据结构,然后写出一个.py文件。
你可以使用Python的inspect
模块来打印一个对象的源代码。就你的情况来说,就是打印你用IronPython解析的那个文件的源代码。不过,我还没确认inspect
在IronPython上是否能用。
至于添加东西,嗯,这就是一个模块,对吧?你可以直接往模块里添加东西……我会先加载这个模块,然后对它进行修改,使用inspect
查看并打印出来,最后保存到磁盘上。
从你的帖子来看,你似乎已经深入研究这个问题并且玩得很开心,所以我会很高兴看到你在这里分享你是如何解决这个问题的!
你想要一个源代码到源代码的程序转换工具。
这个工具会把一种编程语言解析成内部的数据结构(通常是抽象语法树,简称AST),然后允许你修改这个AST,最后再从修改后的AST生成源代码文本,除了AST修改的地方,其他的基本上不会变。
这样的程序转换工具需要把文本解析成AST,然后再把AST“反解析”(称为“美化打印”)成文本。如果IronPython有一个美化打印工具,那就是你需要的。如果没有,你可能需要花费一些(甚至很多)精力来自己制作一个;正如你所观察到的,这并没有想象中那么简单。你可以看看我在将AST编译回源代码的回答。
如果这个方法不行,我们的DMS软件重构工具包,配合它的Python前端,可能会帮到你。它具备上述所有功能。