关于`kur.engine.Engine._evaluate`如何运作的困惑

时间:2017-03-27 03:20:12

标签: python

问题

kur.engine.Engine._evaluate的使用似乎存在冲突。

当我在kur dump mnist.yml目录下运行kur/example/并查看正在运行的详细信息时,我得到了:

enter image description here

但是,当我运行eng = kur.engine.Engine()然后eng._evaluate('mnist-defaults.yml')时,我收到以下错误:

enter image description here

源代码说了什么?

我阅读这个功能doc: 1.将一个字符串作为arg命名表达式 2.返回一个python对象或类

我读这段代码: 我给函数一个字符串arg 2.它返回一个名为' Not Implemented Error'

的错误
def _evaluate(self, expression):
    """ Evaluates a string expression in the current scope.

        # Arguments

        expression: str. The string to evaluate.

        # Return value

        The evaluated expression (some Python object/class)
    """
    # pdb.set_trace()
    raise NotImplementedError

但是,实际上它在doc kur dump mnist.yml中运行时就像doc所说的那样工作。那么,我的理解出错了?谢谢!

2 个答案:

答案 0 :(得分:1)

Engineabstract base class。这意味着旨在直接实例化。相反,它的派生类使用基类作为“模板”(可以说)来扩展其功能。这是object-oriented programming中的经典模式,特别是在Java和C ++等语言中。 Python是一种非常灵活的语言,并且有很多方法可以实现类似的设计模式(例如,abc模块,鸭子类型或经典继承加上良好的文档和NotImplementedError)。 / p>

在您的特定情况下,当您实际运行Kur时,引擎的实例化(运行时)类型 not Engine;它是JinjaEngine。因此,当进行_evaluate()调用时,它实际上是处理它的JinjaEngine,而不是基类(正如您正确指出的那样,引发异常)。尝试实例化JinjaEngine,您应该得到预期的结果。

答案 1 :(得分:0)

基于上面的@ajsyp评论:

  

你肯定是在实例化Engine,它是一个抽象的基类,不应该这样做。当Kur实际运行时,或者如果你想获得预期的行为,那么实例化一个JinjaEngine。抽象基类是一种说法,“这就是这种类型的对象的行为方式”而不实际创建其中一个对象;相反,派生类负责实现基类的行为。这是标准的OOP模式

如果我理解正确,在运行kur -vv build mnist.yml时,当我使用记录器显示kur.Kurfile.parse_source下的工作功能时,我注意到以下几点:

[INFO 2017-04-11 14:05:05,946 kur.kurfile parse:97] (self): after initialize Kurfile object, we parse it: 1. evaluate all section dicts in spec.data with scopes; 2. as a result, spec.data added section aliases (like training, testing);3. other uses here to be answered ....; 4. assign spec.data['templates'] to spec.templates; 3. convert spec.data['model'] into model as containers, and store the list of containers inside spec.contaienrs ; 5. return Nothing
[INFO 2017-04-11 14:05:05,946 kur.kurfile _parse_section:1006]
[DEBUG 2017-04-11 14:05:05,946 kur.kurfile _parse_section:1011] _parse_section(): Parsing Kurfile section: settings
[INFO 2017-04-11 14:05:05,947 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,947 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,947 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,947 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,947 kur.kurfile _parse_section:1006]
[DEBUG 2017-04-11 14:05:05,947 kur.kurfile _parse_section:1011] _parse_section(): Parsing Kurfile section: train
[INFO 2017-04-11 14:05:05,947 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,948 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,949 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,949 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,950 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,950 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,951 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,951 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,951 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,951 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,952 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,952 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
[INFO 2017-04-11 14:05:05,952 kur.engine.jinja_engine _evaluate:123] (self, expression): convert a yml expression (a string) to a python object
[INFO 2017-04-11 14:05:05,953 kur.engine.engine evaluate:209] (self, expression, recursive=False): Evaluates an string expression in the current scope, as itself: (how does scope help evaluate expression? Not sure how is scope used); if expression is not a string, then do some recursion.
  1. 当代码在kur.Kurfile.parse运行时,它会解析不同的部分,例如settingstrainvalidate ......
  2. 在执行kur.Kurfile._parse_section时,大多数部分需要运行大量kur.engine.engine.Engine.evaluate和一些kur.engine.jinjiaEngine.JinjaEngine._evaluate
  3. 我应该通过以下方式理解评论和观察结果:

    1. kur.engine.engine.Engine.evaluatekur.engine.engine.Engine._evaluate是基类方法,实际上我不需要理解它们的内部;是不是?
    2. kur.engine.jinja_engine.JinjaEngine._evaluate是上面基本方法的派生方法,我需要了解它的实际意义;是不是?
    3. 我对kur.engine.jinja_engine.JinjaEngine._evaluate的理解:将yaml字符串表达式转换为python对象。这是对的吗?
    4. 如果没有,你能用一个例子解释一下吗? (不必是工作代码,只是我们可以在脑海中想象的一个例子也可以)

      由于

      @ajsyp进一步的答案和解释非常有帮助

        

      1。)根据定义,Engine类中定义的所有函数都是基类方法。 暗示它们并不重要。它们非常重要!具体来说,Engine.evaluate()实际上是有效的,试图弄清楚如何处理数据,它是什么类型,是否需要递归等等。Engine._evaluate定义派生类必须实现的API (尽管从纯代码的角度来看,Engine._evaluate()不会执行任何事情,因为它的工作是定义API,并将所有实现委托给派生类。   2.)是的,JinjaEngine._evaluate()是派生类方法。在这种特殊情况下,它实现了父类API所定义的逻辑。   3.)有点。 JinjaEngine._evaluate()负责使用Kurfile的当前值来评估Jinja2表达式(不是YAML表达式; YAML解析器已经这样做了;实际上,您可能已经使用了JSON Kurfile,而这整个答案是尚真)。 Jinja2表达式的评估结果是Python表达式的字符串表示形式。因此,如果需要,函数还需要解释该字符串以构造基础Python类型(例如,整数4与字符串“4”)。