如果既不是按位运算也不是 print chevron,>> 是做什么的?
What does >> do if it is neither bitwise operation nor print chevron?
有没有人可以帮助弄清楚双大于号(即第 10 行中的 Drug >> float
和第 13 行中的 Drug >> int
)在以下 python 脚本中的含义?
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
位。
虽然之前问过类似的问题(见python2中的here and ), their answers mostly pointed to the so-called "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'
虽然有了回溯信息,我还是找不到答案。如果有人能帮助弄清楚 >>
在代码中的作用,我将不胜感激。
Drug >> float
调用 Drug
的 __rshift__
方法。该方法可以为所欲为;它不一定是二进制移位操作。
阅读 the owlready2 documentation 表明 domain >> range
是创建 ObjectProperty
的奇特方式。
has answered the question in brief. Below is just to save time for those who don't want to download and parse the source codes of owlready2 但仍想跟踪它在实际代码中的工作原理。
Drug
是在另一个对象ThingClass
的基础上创建的对象,定义在/owlready2/entity.py.
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)
,其实是不是做的二进制算术运算,但 returns/creates DataProperty 或 ObjectProperty,具体取决于 Range 的类型。
有没有人可以帮助弄清楚双大于号(即第 10 行中的 Drug >> float
和第 13 行中的 Drug >> int
)在以下 python 脚本中的含义?
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
位。
虽然之前问过类似的问题(见python2中的here and >>
将待打印的消息重定向到紧接着指定的类文件对象>>
。它们不适用于我的问题,因为这里不是打印语句的情况。
为了追踪上面代码中的>>
,我将第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'
虽然有了回溯信息,我还是找不到答案。如果有人能帮助弄清楚 >>
在代码中的作用,我将不胜感激。
Drug >> float
调用 Drug
的 __rshift__
方法。该方法可以为所欲为;它不一定是二进制移位操作。
阅读 the owlready2 documentation 表明 domain >> range
是创建 ObjectProperty
的奇特方式。
Drug
是在另一个对象ThingClass
的基础上创建的对象,定义在/owlready2/entity.py.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)
,其实是不是做的二进制算术运算,但 returns/creates DataProperty 或 ObjectProperty,具体取决于 Range 的类型。