You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python动态创建本体类?JSON转本体类报错求助

问题描述

尝试将包含随机字典数据的JSON文件转换为本体类,需要动态创建类,但运行代码时触发错误。

代码示例

attributs_data = data.get("attributs", {}) # 提取JSON中的attributs数据
if isinstance(attributs_data, dict):
    attributs = Attributs()
    document.has_attributs = attributs
    for key, value in attributs_data.items():
        prop_name = f"has_{key}"

        # 在本体上下文内定义动态属性
        with onto:
            # 根据值的类型创建对应类
            if isinstance(value, str):
                prop_cls = types.new_class(prop_name, (FunctionalProperty,),
                                           kwds={"domain": [Attributs], "range": [str]})

            elif isinstance(value, dict):
                nested_cls = types.new_class(key.replace(" ", "_").capitalize(), (Thing,))
                nested_instance = nested_cls()
                setattr(attributs, prop_name, nested_instance)
                for subkey, subvalue in value.items():
                    nested_prop_name = f"has_{subkey}"
                    with onto:
                        if isinstance(subvalue, str):
                            nested_prop_cls = types.new_class(nested_prop_name, (FunctionalProperty,),
                                                              kwds={"domain": [nested_cls], "range": [str]})
                        elif isinstance(subvalue, int):
                            nested_prop_cls = types.new_class(nested_prop_name, (FunctionalProperty,),
                                                              kwds={"domain": [nested_cls], "range": [int]})
                        elif isinstance(subvalue, float):
                            nested_prop_cls = types.new_class(nested_prop_name, (FunctionalProperty,),
                                                              kwds={"domain": [nested_cls], "range": [float]})
                        elif isinstance(subvalue, bool):
                            nested_prop_cls = types.new_class(nested_prop_name, (FunctionalProperty,),
                                                              kwds={"domain": [nested_cls], "range": [bool]})
                        setattr(nested_instance, nested_prop_name, subvalue)

错误信息

File "jsonToOwl.py", line 115, in <module>
    prop_cls = types.new_class(prop_name, (FunctionalProperty,),
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/types.py", line 74, in new_class
    return meta(name, resolved_bases, ns, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: EntityClass.__new__() got an unexpected keyword argument 'domain'
解决思路

这个错误的核心是错误地通过types.new_class的kwds参数传递domain、range属性——本体框架(如Owlready2)的EntityClass构造函数不支持这种传参方式。正确做法是先创建属性类,再手动设置这些属性。

修正步骤

  1. 调用types.new_class时,只传入类名和父类,不传递kwds参数
  2. 在with onto:上下文内,给新创建的属性类手动赋值domain和range

以字符串类型属性的创建为例,修正后的代码:

if isinstance(value, str):
    # 先创建属性类,仅指定类名和父类
    prop_cls = types.new_class(prop_name, (FunctionalProperty,))
    # 手动设置domain和range
    prop_cls.domain = [Attributs]
    prop_cls.range = [str]

嵌套属性的创建同理,比如处理子字典中的整数属性:

elif isinstance(subvalue, int):
    nested_prop_cls = types.new_class(nested_prop_name, (FunctionalProperty,))
    nested_prop_cls.domain = [nested_cls]
    nested_prop_cls.range = [int]

额外注意事项

  • 确保Attributs、Thing、FunctionalProperty等类来自你使用的本体库,且已正确关联到onto实例
  • 所有动态类的创建操作必须在with onto:上下文内执行,否则类不会被注册到本体中

内容的提问来源于stack exchange,提问作者pleijan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 07:19:56