Python:如何启用和禁用函数?
我有一个树莓派,上面装了一个红外传感器。在我的Python脚本里,有一个线程类可以监听一个imap服务器(接收像START或STOP这样的指令)。我现在的想法是通过电子邮件发送命令,一旦脚本收到命令,就应该禁用一些功能,直到收到新的命令为止。但我现在最大的问题是,我不知道该怎么实现这个功能。
def take_picture():
...
def take_video():
...
class EmailThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
....
if get_mail == 1:
if var_subject == 'STOP':
#TODO: stop take_picture(), take_video()
pass
elif var_subject == 'START':
#TODO: start take_picture(), take_video()
pass
else:
print u'Wrong command'
time.sleep(600) #google doesn't like many connections within 10min
def main():
# Start eMail Thread
email = EmailThread()
email.start()
try:
print "Waiting for PIR to settle ..."
# Loop until PIR output is 0
while GPIO.input(GPIO_PIR) == 1:
Current_State = 0
print "Ready"
# Loop until threadingusers quits with CTRL-C
while True :
# Read PIR state
Current_State = GPIO.input(GPIO_PIR)
if Current_State == 1 and Previous_State == 0:
counter = counter + 1
# PIR is triggered
start_time = time.time()
log_to_file('Motion Nr. %s detected!' % counter)
take_picture()
# Record previous state
Previous_State = 1
elif Current_State == 0 and Previous_State == 1:
# PIR has returned to ready state
stop_time=time.time()
print " Ready ",
elapsed_time=int(stop_time-start_time)
print " (Elapsed time : " + str(elapsed_time) + " secs)"
Previous_State = 0
except KeyboardInterrupt:
print "Quit "
# Reset GPIO settings
GPIO.cleanup()
if __name__ == '__main__':
main()
3 个回答
0
我觉得在这种情况下,self.enabled应该可以用吧?
def __init__(self):
self.enabled=True
threading.Thread.__init__(self)
然后把启用状态切换为真或假?
2
在初始化的时候,你可以添加一个函数和布尔值(真或假)之间的映射,像这样:
class ClassWithTheFunctions:
def __init__(self):
import types
#...
self.funcMap = {}
for o in self.__dict__:
if type(self.__dict__[o]) == types.FunctionType or type(self.__dict__[o]) == types.MethodType:
self.funcMap[self.__dict__[o]] = True
当你想调用一个函数时,先检查一下它的状态。
if instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] :
funcIWantToCall()
如果你想禁用一个函数:
instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] = False
或者想启用它:
instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] = True
2
我觉得你的问题标题起得不太好。你想做的应该是启动和停止正在运行某些功能的线程。启动一个线程比较简单,但停止它就稍微复杂一些,这取决于这个功能内部是怎么运作的。
你需要了解一下线程之间的通信方法,特别是条件变量
。一般来说,线程只有在允许你停止的时候才能优雅地停止,比如说它在等待某个条件变量的时候。
如果你其实不想用线程,而是想定期运行当前活跃的功能,那你就需要实现一个调度器——在最简单的情况下,调度器会不断循环遍历活跃功能的列表,并调用它们。
我建议你使用后者,因为线程通常会带来不必要的复杂性和错误源,但从你的问题来看,你似乎很想尝试前者。