使用单个全局变量

时间:2018-06-16 13:57:17

标签: python python-3.x loops variables global-variables

我确定我在想这个错误,但我无法弄清楚如何走出死胡同。

我正在建立一个程序,根据外部输入独立闪烁LED。我的代码适用于单个LED。但是,我能想到的让它适用于多个LED的每一种方式都显得愚蠢。

基本上,我希望函数的所有实例都以相同的全局变量开头,但是一旦它们开始烹饪就会以自己的方式继续。这是当前代码的相关部分:

counter = 0
time_from_start = 0
new_average = 0

#eventually this will be get_new_average(sensor_number)
def get_new_average():
    #average is going to be time in .... ms?
    #eventually it will be the average from the arduino
    new_average = int(input("new average? "))

def lighter_up(light_number, intensity):
    print("lighter_up intensity = " + str(intensity))
    #this line needs to be modified to whatever the intensity should be
    strip.setPixelColorRGB(light_number, intensity, 0, 0)
    strip.show()
    return intensity + 1

def lighter_down(light_number, intensity):
    print("lighter_down value = " + str(255 - (intensity - 255)))
    #this line needs to be modified to whatever the intensity should be
    strip.setPixelColorRGB(light_number, 255 - (intensity - 255), 0, 0)
    strip.show()
    return intensity + 1

def heartbeat(light):
    #acknowledge that counter is a global variable
    global counter
    global start_time

    if counter == 0:
        get_new_average()
        #this counts seconds from an arbitrary start point
        start_time = int(time.perf_counter())
        counter = 1
    #the 255 value is arbitrary
    #need to change it when you figure out the flash
    elif 0 < counter < 255:
        counter = lighter_up(light, counter)
    elif 254 < counter <510:
        counter = lighter_down(light, counter)
    elif counter > 509:
        #turn off the light
        strip.setPixelColorRGB(light, 0, 0, 0)
        strip.show()
        #difference between the start time and now
        time_from_start = int(time.perf_counter()) - start_time
        print(time_from_start)
        #if the time from the start of the flash is less than the
        #duration of the heartbeat, as defiend by new_average
        if time_from_start < new_average:
            #just wait it out
            pass
        #if the time from start has hit the new_average
        #it is time for a new heartbeat
        elif time_from_start >= new_average:
            counter = 0
        else:
            print("There was an error in heartbeat()")
    else:
        print("error: counter = " + str(counter))
while True:
    heartbeat(0)

我想在末尾添加一个heartbeat(1)来控制最终连接到第二个传感器的第二个灯。但是,这样做会使“计数器”变为“反击”。来自心跳(0)和&#39;计数器&#39;来自heartbeat(1)冲突(并且会对time_from_start和new_average产生相同的影响)。

我可以创建一个全局变量列表(&#39; counter0&#39;,&#39; counter1&#39;等),但这看起来很愚蠢和不优雅。我也可以在heartbeat()内部移动计数器,但是每次循环时它都会重置为零,什么都不会发生。必须有更好的方法!

我强烈怀疑(希望?)这是一个非常常见的python,有一个非常明显的解决方案。我无法找到它。有什么想法吗?

感谢

1 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您正在寻找的方法是为每个&#34;灯&#设置不同的变量集countertime_from_startnew_average 34;,这样你就可以独立地将你的功能应用到每个灯光而不会覆盖其他灯光的变量?#/ p>

如果是,pythonic解决方案是定义一个类并为每个灯创建一个实例。然后你的函数成为类的方法,每个实例都有它自己的状态(变量集):

class Light(object):
    def __init__(self, number):
       self.number = number
       self.counter = 0
       self.time_from_start = 0
       self.new_average = 0

    def get_new_average(self):
        self.new_average = int(input("new average? "))

    def lighter_up(self, intensity):
        print("lighter_up intensity = " + str(intensity))
        #this line needs to be modified to whatever the intensity should be
        strip.setPixelColorRGB(self.number, intensity, 0, 0)
        strip.show()
        return intensity + 1

    def lighter_down(light_number, intensity):
        print("lighter_down value = " + str(255 - (intensity - 255)))
        #this line needs to be modified to whatever the intensity should be
        strip.setPixelColorRGB(self.number, 255 - (intensity - 255), 0, 0)
        strip.show()
        return intensity + 1

    def heartbeat(self):
        if self.counter == 0:
            self.get_new_average()
            #this counts seconds from an arbitrary start point
            start_time = int(time.perf_counter())
            self.counter = 1

        #the 255 value is arbitrary
        #need to change it when you figure out the flash
        elif 0 < self.counter < 255:
            self.counter = self.lighter_up(self.counter)
        elif 254 < self.counter <510:
            self.counter = self.lighter_down(self.counter)
        elif counter > 509:
            #turn off the light
            strip.setPixelColorRGB(light, 0, 0, 0)
            strip.show()
            #difference between the start time and now
            self.time_from_start = int(time.perf_counter()) - start_time
            print(self.time_from_start)
            #if the time from the start of the flash is less than the
            #duration of the heartbeat, as defiend by new_average
            if self.time_from_start < self.new_average:
                #just wait it out
                pass
            #if the time from start has hit the new_average
            #it is time for a new heartbeat
            elif self.time_from_start >= self.new_average:
                self.counter = 0
            else:
                print("There was an error in heartbeat()")
        else:
            print("error: counter = " + str(self.counter))


lights = [Light(0), Light(1)]
while True:
   for light in lights:
       light.heartbeat()