如果既不是按位运算也不是打印V形,该怎么办?

时间:2018-07-04 22:11:29

标签: python syntax arguments operators

在下面的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位。

尽管之前也曾提出过类似的问题(请参阅herehere),但他们的回答大多指向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'

尽管有了追溯信息,我仍然找不到答案。如果有人可以帮助弄清>>在代码中的作用,我将非常感谢。

2 个答案:

答案 0 :(得分:3)

Drug >> float调用Drug的{​​{3}}方法。这种方法可以做任何想做的事。不必是二进制移位操作。

阅读__rshift__揭示了domain >> range是创建ObjectProperty的理想方式。

答案 1 :(得分:2)

Aran-Fey已简要回答了该问题。以下只是为那些不想下载并解析owlready2的源代码但仍想在实际代码中跟踪其工作方式的用户节省时间的方法。

  1. Drug是根据/owlready2/entity.py中定义的另一个对象ThingClass创建的对象。
  2. Drug >> float呼叫Drug.__rshift__(self, float) [explained]。
  3. 不是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
    
  4. Drug >> float等效于__rshift__(Domain=Drug, Range=float),实际上 不是 进行二进制算术运算,但是返回/创建一个DataProperty或ObjectProperty,取决于Range的类型。