这与 this 问题类似,只不过这里有效的参数包含在 json 文件中。
在使用 VSCode 的 Python 中,我想定义一个基于 JSON 文件内容的类型。这样的事可能吗?
例如,
data.json
包含三个对象的数据:an_option
、another_option
和 yet_another_option
。
{
"data": [
{
"id":"an_option",
"prorty":"value"
},
{
"id":"another_option",
"prorty":"value"
},
{
"id":"yet_another_option",
"prorty":"value"
}
]
}
在
main.py
中,我定义了一种类型,允许 Intellisence 在写入该类型的数据时建议这些选项。调用 test_function
时,Intellisense 建议我的选项作为参数。
from typing import Literal
MyType = Literal[
"an_option",
"another_option",
"yet_another_option"
]
def test_function(option_chosen: MyType):
print(option_chosen)
pass
test_function("an_option")
但是,那么我的选项名称必须复制到多个文件中,这看起来很麻烦。当我从
MyType
将条目添加到 data
列表时,我希望更新 data.json
类型。例如,类似
from typing import Literal
import json
file = open('data.json', 'r')
data = json.load(file)
list_of_options_with_properties = data["data"]
option_name_list = list()
for option in list_of_options_with_properties:
option_name_list.append(option["id"])
MyType = Literal[tuple(option_name_list)]
def test_function(option_chosen: MyType):
print(option_chosen)
pass
test_function("an_option")
不幸的是,这对自动完成没有帮助,因为
option_name_list
直到运行时才定义。是否可以让Intellisense读取json文件的内容来定义类型?
直接使用 Python 的类型系统,这是不可行的,因为静态类型检查器在代码执行之前运行。但是,您可以使用代码生成工具制定解决方案。您可以编写一个脚本来读取 JSON 文件并自动更新具有相关
Literal
类型的模块。
# codegen.py
import json
from typing import List
def generate_literal_type_from_json(filename: str) -> List[str]:
with open(filename, 'r') as f:
data = json.load(f)
options = [item["id"] for item in data["data"]]
return options
if __name__ == "__main__":
options = generate_literal_type_from_json("data.json")
with open("generated_types.py", "w") as f:
f.write(f"from typing import Literal\n\n")
f.write(f"MyType = Literal{tuple(options)}\n")
运行此脚本,它将生成一个
generated_types.py
文件。然后,您可以在生成的文件的主代码中使用 MyType
类型。