TL;DR:您以字典的形式MappingRule
将数据传递给您的Action
(例如Key
,Text
),因此每次额外只能传递一个值。您现在最好的选择可能是创建多个附加功能。
这是蜻蜓解析识别的方式的副作用。我将首先用Action
对象来解释它,然后我们可以分解为什么会在Rule
关卡中发生这种情况。
当 Dragonfly 收到识别时,它必须解构它并提取发生的任何额外内容。语音识别引擎本身对多次出现相同的extra没有问题,它确实将数据传递给dragonfly,但dragonfly会丢失该信息。
所有Action
对象都派生自ActionBase
,这是蜻蜓想要执行时调用的方法Action
:
def execute(self, data=None):
self._log_exec.debug("Executing action: %s (%s)" % (self, data))
try:
if self._execute(data) == False:
raise ActionError(str(self))
except ActionError as e:
self._log_exec.error("Execution failed: %s" % e)
return False
return True
这就是Text
工作原理,与Key
. 这里没有记录,但data
它是映射到值的附加字典。例如:
{
"n": "3",
"text": "some recognized dictation",
}
看到问题了吗?这意味着我们只能传达每个额外的单个值。即使我们结合多个动作,我们也会遇到同样的问题。例如:
{
"down <n> <n>": Key("%(n)d") + Text("%(n)d"),
}
在引擎盖下,这两个动作组合成一个ActionSeries
对象 - 一个动作。它公开了相同的execute
接口。一系列动作,一个data
命令。
请注意,复合规则不会发生这种情况,即使每个基础规则共享一个具有相同名称的额外规则。那是因为data
被解码并通过per-rule。每个规则将不同的data
字典传递给Action
它希望执行的。
如果您对我们失去第二个额外的地方感到好奇,我们可以在调用链上导航。
每个规则都有一个process_recognition
方法。这是发生识别时调用的方法。它采用当前规则node
并对其进行处理。这node
可能是一棵规则树,也可能是较低级别的东西,例如Action
. 让我们看一下中的实现MappingRule
:
def process_recognition(self, node):
"""
Process a recognition of this rule.
This method is called by the containing Grammar when this
rule is recognized. This method collects information about
the recognition and then calls *self._process_recognition*.
- *node* -- The root node of the recognition parse tree.
"""
# Prepare *extras* dict for passing to _process_recognition().
extras = {
"_grammar": self.grammar,
"_rule": self,
"_node": node,
}
extras.update(self._defaults)
for name, element in self._extras.items():
extra_node = node.get_child_by_name(name, shallow=True)
if extra_node:
extras[name] = extra_node.value()
elif element.has_default():
extras[name] = element.default
# Call the method to do the actual processing.
self._process_recognition(node, extras)
我将跳过一些复杂性 -extras
您在此处看到的变量是data
字典的早期形式。看看我们在哪里失去了价值?
extra_node = node.get_child_by_name(name, shallow=True)
看起来像:
def get_child_by_name(self, name, shallow=False):
"""Get one node below this node with the given name."""
for child in self.children:
if child.name:
if child.name == name:
return child
if shallow:
# If shallow, don't look past named children.
continue
match = child.get_child_by_name(name, shallow)
if match:
return match
return None
所以,你看到了这个问题。Dragonfly 尝试为每个额外的值提取一个值,它得到第一个值。然后,它将该值填充到字典中并将其传递给Action
. 其他事件丢失。