我只是有3个模式的枚举器ledOn,ledBlink,ledOFF我有一个可变模式,可以跟踪特定对象的模式。所以例如我有一个LED启动模式ledOn我想例如在5秒后移动到下一个元素,然后ledBlink然后到ledOFF然后循环到ledON有一个简单的方法来实现这样的事情吗? / p>
import time
from threading import Thread
from enum import Enum
class ledController(Thread):
ledModes = Enum('ledModes', 'ledON ledBlink ledOFF')
def __init__(self, GPIOID, state=False, blinkDuration=2, mode=ledModes.ledON):
self.GPIOID = GPIOID
self.state = state
self.blinkDuration = blinkDuration
self.mode = mode
self.blinked = False
Thread.__init__(self)
def run(self):
if(self.mode == self.ledModes.ledON):
self.ledON()
if(self.mode == self.ledModes.ledBlink):
self.ledBlink()
if(self.mode == self.ledModes.ledOFF):
self.ledOFF()
time.sleep(self.blinkDuration)
self.mode.next()
def ledSwitch(self):
self.state = not self.state
print(self.ledDetails())
def ledON(self):
self.state = True
print(self.ledDetails())
def ledOFF(self):
self.state = False
print(self.ledDetails())
def ledBlink(self, duration):
self.ledON()
print(self.ledDetails())
time.sleep(self.Blinkduration)
self.ledOFF()
print(self.ledDetails())
time.sleep(self.Blinkduration)
def ledDetails(self):
return "Thread: "+self.getName()+", LED: "+str(self.GPIOID)+", State: "+str(self.state)+", Mode: "+str(self.mode.name)+", Blink duration: "+str(self.blinkDuration)
redLED = ledController(17, blinkDuration = 3)
blueLED = ledController(18, mode = ledController.ledModes.ledOFF)
redLED.setName('1')
blueLED.setName('2')
redLED.start()
blueLED.start()
redLED.join()
blueLED.join()
答案 0 :(得分:1)
我只会使用itertools.cycle代替您的枚举:
>>> from itertools import cycle
>>> ledModes = cycle(['ledON', 'ledBlink', 'LedOFF'])
>>> first = next(ledModes)
>>> second = next(ledModes)
>>> third = next(ledModes)
>>> fourth = next(ledModes)
>>>
>>> first
'ledON'
>>> second
'ledBlink'
>>> third
'LedOFF'
>>> fourth
'ledON'
>>>
仅供参考,你可以next(ledModes)
或ledModes.next()
,两者都是一样的。
编辑:您可以使用类似的方法,作为班级的方法:
from itertools import cycle
def initialize_cycle(start_mode):
states = ['ledON', 'ledBlink', 'ledOFF']
if start_mode not in states:
raise ValueError('start_mode invalid')
iterable = cycle(states)
for _ in states[:states.index(start_mode)]:
iterable.next()
return iterable
test1 = initialize_cycle('ledON')
test2 = initialize_cycle('ledOFF')
test3 = initialize_cycle('ledBlink')
# validation
for test in test1, test2, test3:
for _ in range(5):
print test.next()
print '-' * 20
输出:
$ python cycle.py
ledON
ledBlink
ledOFF
ledON
ledBlink
--------------------
ledOFF
ledON
ledBlink
ledOFF
ledON
--------------------
ledBlink
ledOFF
ledON
ledBlink
ledOFF
--------------------
答案 1 :(得分:1)
您当前代码的最简单修复方法是:
run
方法和next_mode
方法:def run(self):
while True:
set_mode = getattr(self, self.mode)
set_mode()
time.sleep(self.blinkDuration)
self.next_mode()
def next_mode(self):
self.mode = {
self.ledModes.ledON: self.ledModes.ledBlink,
self.ledModes.ledBlink: self.ledModes.ledOFF,
self.ledModes.ledOff: self.ledModes.ledOn,
}[self.mode]
答案 2 :(得分:1)
可能是一种矫枉过正的行为:
import itertools
class EnumCycler(object):
def __init__(self, enum, start_at=None):
self.enum = enum
self.members = list(enum.__members__.values())
self.start_at = self.members[0] if start_at is None else start_at
self.cycles = 0
def __iter__(self):
cycle = itertools.cycle(self.members)
sanity_check = len(self.members)
for value in cycle:
if sanity_check:
if value != self.start_at:
sanity_check -= 1
continue
sanity_check = 0
self.cycles += 1
yield value
然后:
>>> mode = Enum('ledModes', 'ledON ledBlink ledOFF')
>>> led_mode_cycler = EnumCycler(mode, start_at=mode.ledOFF)
>>> for value in led_mode_cycler:
... print(led_mode_cycler.cycles, value)
... if led_mode_cycler.cycles >= 10: break # infinite loop if we never break off
1 ledModes.ledOFF
2 ledModes.ledON
3 ledModes.ledBlink
4 ledModes.ledOFF
5 ledModes.ledON
6 ledModes.ledBlink
7 ledModes.ledOFF
8 ledModes.ledON
9 ledModes.ledBlink
10 ledModes.ledOFF