在下面的python脚本中,是否有人可以帮助找出大于号的两倍符号(即第10行中的Drug >> float
和第13行中的Drug >> int
)?
1 from owlready2 import *
2
3 onto = get_ontology("http://test.org/onto.owl")
4
5 with onto:
6 class Drug(Thing):
7 def get_per_tablet_cost(self):
8 return self.cost / self.number_of_tablets
9
10 class has_for_cost(Drug >> float, FunctionalProperty):
11 python_name = "cost"
12
13 class has_for_number_of_tablets(Drug >> int, FunctionalProperty):
14 python_name = "number_of_tablets"
15
16 my_drug = Drug(cost = 10.0, number_of_tablets = 5)
17 print(my_drug.get_per_tablet_cost())
--- Below is the printing outcome. ---
2.0
该代码是从here复制并在python 3中运行的。
此处的>>
符号不是按位运算符。 Python's bitwise operation,例如x >> y
,要求y
是整数。显然,此处的代码(Drug >> float
没有将Drug
右移float
位。
尽管之前也曾提出过类似的问题(请参阅here和here),但他们的回答大多指向python 2中的所谓的"print chevron",其中>>
进行了重定向>>
之后立即将要打印的消息发送到指定的文件状对象。它们不适用于我的问题,因为这里不是印刷声明。
要跟踪上面的代码中的>>
,我将第10行的脚本修改为class has_for_cost(Drug >> list, FunctionalProperty)
(即用>> float
替换了>> list
)并再次运行了代码。它引发了AttributeError,如下所示:
AttributeError Traceback (most recent call last)
<ipython-input-1-1be374b27b04> in <module>()
8 return self.cost / self.number_of_tablets
9
---> 10 class has_for_cost(Drug >> list, FunctionalProperty):
11 python_name = "cost"
12
~/anaconda3/lib/python3.6/site-packages/owlready2/prop.py in __init__(Prop, name, bases, obj_dict)
254 class ReasoningPropertyClass(PropertyClass):
255 def __init__(Prop, name, bases, obj_dict):
--> 256 super().__init__(name, bases, obj_dict)
257
258 if (not Prop.namespace.world is owl_world):
~/anaconda3/lib/python3.6/site-packages/owlready2/prop.py in __init__(Prop, name, bases, obj_dict)
78
79 if not range is False:
---> 80 Prop.range.extend(range)
81
82 if not inverse_property is False:
~/anaconda3/lib/python3.6/site-packages/owlready2/util.py in extend(self, l)
58 def append(self, x): old = list(self); super().append(x) ; self._callback(self._obj, old)
59 def insert(self, i, x): old = list(self); super().insert(i, x) ; self._callback(self._obj, old)
---> 60 def extend(self, l): old = list(self); super().extend(l) ; self._callback(self._obj, old)
61 def remove(self, x): old = list(self); super().remove(x) ; self._callback(self._obj, old)
62 def __delitem__(self, i): old = list(self); super().__delitem__(i) ; self._callback(self._obj, old)
~/anaconda3/lib/python3.6/site-packages/owlready2/prop.py in _range_changed(Prop, old)
143 for x in new - old:
144 if isinstance(x, ClassConstruct): x._set_ontology(Prop.namespace.ontology)
--> 145 x2 = _universal_datatype_2_abbrev.get(x) or x.storid
146 Prop.namespace.ontology.add_triple(Prop.storid, rdf_range, x2)
147
AttributeError: type object 'list' has no attribute 'storid'
尽管有了追溯信息,我仍然找不到答案。如果有人可以帮助弄清>>
在代码中的作用,我将非常感谢。
答案 0 :(得分:3)
Drug >> float
调用Drug
的{{3}}方法。这种方法可以做任何想做的事。不必是二进制移位操作。
阅读__rshift__
揭示了domain >> range
是创建ObjectProperty
的理想方式。
答案 1 :(得分:2)
Aran-Fey已简要回答了该问题。以下只是为那些不想下载并解析owlready2的源代码但仍想在实际代码中跟踪其工作方式的用户节省时间的方法。
Drug
是根据/owlready2/entity.py中定义的另一个对象ThingClass
创建的对象。Drug >> float
呼叫Drug.__rshift__(self, float)
[explained]。不是Drug
而是具有ThingClass
方法的基础对象__rshift__
,该方法读取entity.py:
class ThingClass(EntityClass):
...
def __rshift__(Domain, Range):
import owlready2.prop
owlready2.prop._next_domain_range = (Domain, Range)
if isinstance(Range, ThingClass) or isinstance(Range, ClassConstruct):
return owlready2.prop.ObjectProperty
else:
return owlready2.prop.DataProperty
Drug >> float
等效于__rshift__(Domain=Drug, Range=float)
,实际上 不是 进行二进制算术运算,但是返回/创建一个DataProperty或ObjectProperty,取决于Range的类型。