Python 使用蜻蜓组合规则时重复一个额外的
使用语音命令框架,您可以生成如下语法:Python 使用蜻蜓组合规则时重复一个额外的,python,speech-recognition,python-dragonfly,Python,Speech Recognition,Python Dragonfly,使用语音命令框架,您可以生成如下语法: chrome_rules = MappingRule( name='chrome', mapping={ 'down [<n>]': actions.Key('space:%(n)d'), }, extras=[ IntegerRef("n", 1, 100) ], defaults={ "n": 1 } ) chrome\u rules=
chrome_rules = MappingRule(
name='chrome',
mapping={
'down [<n>]': actions.Key('space:%(n)d'),
},
extras=[
IntegerRef("n", 1, 100)
],
defaults={
"n": 1
}
)
chrome\u rules=MappingRule(
name='chrome',
映射={
'down[]':actions.Key('space:%(n)d'),
},
额外费用=[
IntegerRef(“n”,1100)
],
默认值={
“n”:1
}
)
这使我可以按空格n
次,其中n
是某个整数。但是,如果我想在同一语法中多次使用同一变量(n
),该怎么办?如果我在语法中重复它,例如,'down'
,然后说“down three-four”之类的话,蜻蜓会正确地解析它,但它只会使用n
的第一个值执行actions.Key('space:%(n)d')
和n=3
。如何让它执行3次,然后使用同一个变量执行4次
理想情况下,我不想在extras和defaults中复制变量
n
,因为这看起来像是冗余代码。TL;DR:您的MappingRule
以字典的形式将数据传递给操作(例如键
,文本
),因此它每额外传递一个值。你现在最好的办法可能是创造多个额外的
这是蜻蜓解析识别方式的副作用。我将首先用Action
对象解释它,然后我们可以在Rule
级别分解为什么会发生这种情况
当蜻蜓收到一个识别,它必须解构它,并提取任何额外发生的。语音识别引擎本身对同一额外事件的多次发生没有问题,它确实会将数据传递给dragonfly,但dragonfly会丢失这些信息
所有Action
对象都来自ActionBase
,这是蜻蜓想要执行操作时调用的方法:
def执行(self,data=None):
self.\u log\u exec.debug(“执行操作:%s(%s)”%(self,数据))
尝试:
如果self.\u execute(数据)=False:
引发操作错误(str(self))
除ActionError外,如e:
self.\u log\u exec.error(“执行失败:%s”%e)
返回错误
返回真值
这就是文本
的工作方式,与键
相同。这里没有文档,但是数据
是一个映射到值的附加值字典。例如:
{
“n”:“3”,
“文本”:“一些公认的听写”,
}
看到问题了吗?这意味着,我们每增加一次只能传达一个值。即使我们将多个动作结合起来,我们也会遇到同样的问题。例如:
{
“向下”:键(“%(n)d”)+文本(“%(n)d”),
}
在引擎盖下,这两个动作组合成一个ActionSeries
对象-一个动作。它公开了相同的execute
接口。一系列动作,一个数据
请注意,复合规则不会发生这种情况,即使每个基础规则共享一个具有相同名称的额外规则。这是因为数据是按照规则解码和传递的。每个规则将不同的数据
dict传递给它希望执行的操作
如果你想知道我们第二个多余的丢失在哪里,我们可以在呼叫链上导航
每个规则都有一个过程\识别
方法。这是发生识别时调用的方法。它接受当前规则的节点
并对其进行处理。这个节点
可能是一个规则树,也可能是较低级别的,比如操作
。让我们看看MappingRule
中的实现:
def过程识别(自身、节点):
"""
处理对该规则的认可。
当发生此错误时,包含语法将调用此方法
已识别规则。此方法收集有关的信息
识别,然后调用*self.\u process\u recognition*。
-*节点*--识别解析树的根节点。
"""
#准备*extras*dict以传递给_process_recognition()。
额外费用={
“_语法”:self.grammar,
“_规则”:自我,
“_节点”:节点,
}
附加更新(自身默认值)
对于名称,self.\u extras.items()中的元素:
extra\u node=node。通过\u名称获取\u子\u(name,shallow=True)
如果是额外的_节点:
extras[名称]=额外节点.值()
elif元素。具有默认值()
extras[名称]=element.default
#调用该方法来执行实际的处理。
自我识别过程识别(节点、附加)
我将略过一些复杂性-您在这里看到的extras
变量是data
字典的早期形式。看到我们失去价值的地方了吗
extra\u node=node.get\u child\u by\u name(name,shallow=True)
这看起来像:
def按名称获取子项(self,name,shall=False):
“”“在此节点下获取一个具有给定名称的节点。”“”
对于在self.children中的children:
如果是child.name:
如果child.name==name:
返回儿童
如果很浅:
#如果肤浅,不要看过去的命名儿童。
持续
match=child.get\u child\u by\u name(name,shall)
如果匹配:
复赛
一无所获
所以,你看到问题了。蜻蜓试图为每一个额外的值提取一个值,它得到第一个值。然后,它将该值填充到字典中,并将其传递给操作
。其他事件将丢失