2017-04-07 116 views
0

我正在监视一个外部设备,当条件不满足时输出一个布尔值为False,当条件满足时,布尔值为True。 问题是,满足条件后,布尔值会多次输出。如何在python中布尔值更改时执行一次函数?

这是输出的样子:

False 
False 
False 
False 
True 
True 
False 
False 
False 

所以我想什么,能够做的就是监控此值,并执行一个简单的功能,只有一次,每次从假到布尔变化真正。我已经看到其他语言具有简单的“变化”功能,所以我知道它可能并且可能比我更容易做到。

目前我有这个。为了解释这一点,变量“ext_data”被用作python脚本正在监视的外部数据。

while True: 
    if ext_data == True: 
     print("true") 
     pass 

这将打印“真”每一次布尔等于真实的,当它重置本身的布尔仍设置为True,所以我得到多个读数时,我只想要一个。

感谢任何人的帮助!

编辑:使用holdenweb写的EdgeDetector类

更新后的代码。

ext_data = True/False # This returns True or False depending on the state 
         # of the variable. It is constantly monitored and 
         # could change at any moment, which is why I'm 
         # running the function in a while True loop 
def printer(): 
    print(u'something%s' % serialport.cts) 
    post_to_api('cycle_count') 

def myfunction(): 
    return ext_data 

test_subject = EdgeDetector(myfunction, printer) 

while True: 

    test_subject.test() 

这仍然返回偶尔重复的帖子。有人提到这个数据需要放在一个数组中才能使EdgeDetector类正常工作,你会如何建议将这些数据放入一个数组而不创建一个无限长的数组?

+0

据我知道,谁提到存储在数组中的数据的唯一的人(名单,其实)是你。当你说它“返回重复的帖子”时,你如何确定?他们的问题的事实是,除非有一个bug(总是可能的),这是不可能的,除非已经有高到低的转换第一(因为技术上我真的应该把它称为RisingEdgeDetector的代码来检测的边缘,但这种假设了解信号的极性)。既然你在投票,你可能会错过短暂的脉冲。如果执行不output_from_device': – holdenweb

回答

2

您的问题被框住的方式并没有说明如何获得外部价值。这必须涉及存储状态信息 - 具体而言,是读取的最后一个值。

虽然可以将其存储在全局变量中,但这不是一种好的做法 - 虽然它可以满足您的直接需求,但如果您尝试基于此创建可重用的软件组件,它将会中断在同一个模块中的其他代码决定使用相同的全局变量出于其他目的的事件。所以一堂课可能会更令人满意。

下面的类被写入来接收一个被调用时返回外部变量的值的函数。这作为参数read_signal传递给班级的__init__。第二个参数,action,是当它检测到一个FalseTrue过渡对象应该调用一个函数。

以这种形式投射意味着您可以轻松地将其整合到任何程序中,并且您应该资助自己必须处理许多外部变量,您可以为每个变量创建一个EdgeDetector

class EdgeDetector: 
    """Detects False to True transitions on an external signal.""" 

    def __init__(self, reader, action): 
     self.reader = reader 
     self.action = action 
     self.last_value = reader() # initialise value 

    def test(self): 
     new_value = self.reader() 
     if new_value and not self.last_value: 
      self.action() 
     self.last_value = new_value 

if __name__ == '__main__':     # simple self-test 
    vlist = [False, False, False, True, True, False, True, True, False, False, False, True] 
    vgen = (v for v in vlist)    # generator for value sequence 

    def test_reader():      # generate test sequence 
     value = next(vgen) 
     print("Read:", value) 
     return value 

    def printer(): 
     print("Edge transition detected") 

    test_subject = EdgeDetector(test_reader, printer) 
    for i in range(len(vlist)-1): 
     test_subject.test() 

通常你会导入此模块到你的程序,使它更容易重新使用,并保持实施细则从主代码得好远。当作为程序运行时,自检代码将显示输入值序列以及何时检测到转换,从而让您在部署代码之前对代码更有信心。自检的输出是

Read: False 
Read: False 
Read: False 
Read: True 
Edge transition detected 
Read: True 
Read: False 
Read: True 
Edge transition detected 
Read: True 
Read: False 
Read: False 
Read: False 
Read: True 
Edge transition detected 
+0

这正是我所期待的,每次搜索边缘检测都会返回关于canny边缘检测的结果以进行图像处理。感谢这样一个详细的答复 –

+0

很高兴能协助 – holdenweb

+0

快速的问题,你会怎么监控生存变量不存储变量的数据时,这样做呢?我尝试将活动变量的最后两个值保存到列表中,然后每次列表中有两个值时重写列表。即该列表将是'[False,False]',然后它会不断被重写,并且我会测试它是否等于'[False,True]',但是我仍然得到双重读数。 –

1

你可以让你保持跟踪关闭(伪代码)的内部变量

executed = false 

if(!executed && output_from_device == true) 
    print("true") 
    executed = true 

但我不知道你的整个安装,所以它可能是最好创建某种形式的事件处理吧而不是一个天真的方法。

+0

'executed'然后应更新为'FALSE'一旦你'output_from_device'changes从TRUE;到'FALSE'像这样执行= FALSE' – pixis

+0

我试着保持像内部变量建议但无法使其工作。我会再给它一次。所以通过更新“执行”为false,这允许循环继续下去,直到下一个实例,是否正确? –

+0

@Dennis是这样写代码的吗?因为我仍然获得多个阅读。 var是布尔数据,我把'\ n'指定为精细换行符 ',而True:\ n 如果未执行,并且var:\ n print(“已执行”)\ n 执行= True \ n if执行的,而不是VAR:\ n 执行=假\ N' –

1

为什么不服用点简单:

#Input Boolean 
inputData = [True,False,False,False,True,True,False] 


foo ='' 

for i in inputData: 
    if foo != i: 
     print("Yo") 
     foo = i 

InputData的第一个元素将触发打印,因为富是空的,那么作为富= True,则下一次打印将被触发时inputData元素将是错误的。 ..等...

+0

因为这是监测实时数据,所以我不认为你可以为循环运行,为上限将是无限大的权利?这需要监控记录的数据,然后通过数据 –

+0

过滤的实时数据和打印(“球”),代替它的那种“而真正的”循环,其中在循环的开始,你从别的东西接收输入,每次你收到这些数据,你都可以检查我写的不是? – NoOne