Owlready2动态创建属性后创建关联报错,求解决及FunctionalProperty释义
嘿,我来帮你拆解这个Owlready2的问题,先逐个解决你遇到的错误,再给你解释FunctionalProperty的含义:
解决Owlready2动态属性创建与赋值的错误
1. 第一个错误:AttributeError: 'list' object has no attribute 'storid'
这个问题的核心是你误解了FunctionalProperty的约束——它是函数型属性,OWL里的规则是:定义域的每个实例只能对应值域的一个实例(就像数学里的函数,一个输入只能有一个输出)。
所以你不能给它赋值列表,得改成直接赋值单个对象:
my_drug.has_for_ingredient = acetaminophen # 去掉方括号,不用列表
这样就能避免列表引发的storid错误了。
2. 第二个错误:AttributeError: 'int' object has no attribute 'namespace'
这个错误大概率是你动态创建属性时,domain和range变量没有正确指向本体里的类(比如你可能没给domain赋值为Drug,而是传了其他类型的值)。动态创建属性时,必须明确把domain和range设置为本体中的类,而且要以列表形式传入。
修正后的完整代码应该是这样:
from owlready2 import * import types # 创建本体实例 onto = get_ontology("http://test.org/drug_onto.owl") with onto: class Drug(Thing): pass class Ingredient(Thing): pass relation_name = "has_for_ingredient" with onto: # 只用ObjectProperty(如果需要支持多值关联的话) NewProperty = types.new_class(relation_name, (ObjectProperty,)) NewProperty.domain = [Drug] # 明确指定定义域为Drug类,用列表包裹 NewProperty.range = [Ingredient] # 明确指定值域为Ingredient类 # 现在赋值多个成分就没问题了 my_drug = Drug("my_drug") acetaminophen = Ingredient("acetaminophen") ibuprofen = Ingredient("ibuprofen") my_drug.has_for_ingredient = [acetaminophen, ibuprofen] # 验证属性创建成功 print(list(onto.properties()))
关于FunctionalProperty的含义
在OWL本体体系里,FunctionalProperty是一种特殊的对象属性,它强制一个约束:对于定义域中的任意个体,最多只能有一个值域的个体与之关联。
举个实际例子:如果我们定义has_birthdate为FunctionalProperty,那么一个人只能有一个出生日期,不能同时有多个;但如果是has_ingredient这种属性,一种药物可能有多种成分,就不能用FunctionalProperty,只用普通的ObjectProperty就可以支持多值关联。
对应到Owlready2中,使用FunctionalProperty混合创建的属性,在赋值时只能接受单个值,不能接受列表——这就是你第一个错误的直接原因。
内容的提问来源于stack exchange,提问作者anna-kay
相关产品推荐
相关产品推荐

