首先亮相,在我看来,有两件事情可以做...
- 继续追求使用Python源文件作为配置文件。 (我不推荐这样做。这是类似于使用推土机撞击钉子或转换a shotgun到车轮)
切换到类似TOML,JSON或YAML的配置文件,这是专为工作。
JSON或YAML中的任何内容都不能阻止它们保持“有序”键值对。 Python的dict
数据类型默认是无序的(至少到3.5),并且list
数据类型是有序的。当使用默认加载器时,它们分别直接映射到JSON中的对象和数组。在对它们进行反序列化时,只需使用Python的OrderedDict
之类的东西,就可以维持秩序!
有了这样的方式,如果你真的想使用Python源文件的配置,我建议尝试处理使用ast
模块文件。抽象语法树是语法级别分析的强大工具。
我鞭打了一个快速脚本,用于从文件中提取类行号和名称。
你(或任何真正的人)可以使用它,或者扩展它以获得更广泛的检查权限,并且可以随时随地进行更多检查。
import sys
import ast
import json
class ClassNodeVisitor(ast.NodeVisitor):
def __init__(self):
super(ClassNodeVisitor, self).__init__()
self.class_defs = []
def visit(self, node):
super(ClassNodeVisitor, self).visit(node)
return self.class_defs
def visit_ClassDef(self, node):
self.class_defs.append(node)
def read_file(fpath):
with open(fpath) as f:
return f.read()
def get_classes_from_text(text):
try:
tree = ast.parse(text)
except Exception as e:
raise e
class_extractor = ClassNodeVisitor()
li = []
for definition in class_extractor.visit(tree):
li.append([definition.lineno, definition.name])
return li
def main():
fpath = "/tmp/input_file.py"
try:
text = read_file(fpath)
except Exception as e:
print("Could not load file due to " + repr(e))
return 1
print(json.dumps(get_classes_from_text(text), indent=4))
if __name__ == '__main__':
sys.exit(main())
这里有以下文件运行示例:
input_file.py
:
class Foo:
pass
class Bar:
pass
输出:
$ py_to_json.py input_file.py
[
[
1,
"Foo"
],
[
5,
"Bar"
]
]
如果我输入example
,
如果你要导入模块,该模块example
要导入的路径上。导入意味着在example
模块中执行任意 Python代码。这是一个非常大的安全漏洞 - 您要在与应用程序其余部分相同的上下文中加载用户可编辑的文件。
这是一个很模糊的想法。你应该给[Figura](https://figura.readthedocs.io/en/latest/)一枪! – shx2
我应该指出在Figura中不保存声明的顺序,[也不在json中](http://stackoverflow.com/a/7214312),也不在YAML中。 – shx2
@ shx2 AFAIK yaml中的订单得到保存。否则,在saltstack中订购状态将无法运行:https://docs.saltstack.com/en/latest/ref/states/ordering。html – guettli