まず、私が見ているように、あなたができることは2つあります...
- 構成ファイルとして Python ソース ファイルを使用することを引き続き追求します。(これはお勧めしません。ブルドーザーを使って釘を打ったり、散弾銃を車輪に変えたりするようなものです)
ジョブ用に設計された構成ファイルをTOML、JSONまたはYAMLなどに切り替えます。
JSON または YAML には、「順序付けられた」キーと値のペアを保持することを妨げるものは何もありません。Python のdict
データ型はデフォルトで順序付けされておらず (少なくとも 3.5 まで)、list
データ型は順序付けられています。これらは、デフォルトのローダーを使用する場合、それぞれ JSON のオブジェクトと配列に直接マップされます。OrderedDict
それらを逆シリアル化するときにPythonのようなものを使用するだけで、順序が保持されます!
それはさておき、構成に 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
モジュールはインポート パス上にあります。インポートとは、モジュール内の任意のPython コードを実行することを意味しexample
ます。これはかなり大きなセキュリティ ホールです。アプリケーションの残りの部分と同じコンテキストで、ユーザーが編集可能なファイルを読み込んでいます。