使用用户输入索引调用函数

时间:2016-12-01 05:55:08

标签: python python-2.7

我试图通过显示列表并要求用户选择列表中项目的索引来调用python 2.7中的函数。我对两点感到困惑:

  1. 用户输入的索引如何对应于初始列表中定义的功能?我了解如何选择列表中的项目,但不了解如何调用函数。

  2. 我应该把这段代码放在哪里?在主要功能?

  3. 这是我的代码:谢谢

    ''' neoPixel setups'''
    import time
    from neopixel import *
    
    # LED configuration.
    LED_COUNT = 16  # Number of LED pixels.
    LED_PIN = 12  # GPIO pin connected to the pixels (must support PWM!).
    LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
    LED_DMA = 5  # DMA channel to use for generating signal (try 5)
    LED_BRIGHTNESS = 255  # Set to 0 for darkest and 255 for brightest
    LED_INVERT = False  # True to invert the signal (when using NPN transistor level shift)
    
    
    def colorWipe(strip, color, wait_ms=50):
        """Wipe color across display a pixel at a time."""
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, color)
            strip.show()
            time.sleep(wait_ms / 1000.0)
    
    
    def theaterChaseRainbow(strip, wait_ms=50):
        """Rainbow movie theater light style chaser animation."""
        for j in range(256):
            for q in range(3):
                for i in range(0, strip.numPixels(), 3):
                    strip.setPixelColor(i + q, wheel((i + j) % 255))
                strip.show()
                time.sleep(wait_ms / 1000.0)
                for i in range(0, strip.numPixels(), 3):
                    strip.setPixelColor(i + q, 0)
    
    
    if __name__ == '_main_':
        # create neopixel object with appropriate configuration
        strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS)
        # initialize the library (must be called before other function)
        strip.begin()
    
        print 'Press Ctrl-C to quit'
    
    ''' user input block '''
    lighting_modes = 'rainbow', 'colorWipe'
    
    for i, item in enumerate(lighting_modes):
        print i, item
    
    user_input = input("Please enter index of the lighting modes listed above")
    
    if user_input == 0:
        colorWipe(strip, Color(255, 0, 0))  # red
        colorWipe(strip, Color(0, 255, 0))  # blue
        colorWipe(strip, Color(0, 0, 255))  # green
    elif user_input == 1:
        theaterChase(strip, Color(127, 127, 127))
        theaterChase(strip, Color(127, 0, 0))
        theaterChase(strip, Color(0, 0, 127))
    

1 个答案:

答案 0 :(得分:4)

>>> def f():
    print('foo')

>>> def g():
    print('bar')

将功能放在列表中

>>> funcs = [f, g]

使用用户的输入索引列表,并将结果分配给名称。

>>> which = int(input('which .. '))
which .. 1
>>> func = funcs[which]

称之为

>>> func()
bar
def fff(arg1, arg2):
    print('f', arg1, arg2)

def ggg(arg1, arg2):
    print('g', arg1, arg2)

根据用户的选择,使用预定的参数多次调用不同的函数 - 您需要将用户的选择与函数和函数相关联,并使用它们将调用的参数。这可以用字典

完成
{choice : [function, [(args), (args), (args)]], ...}

func_f = [fff, [('strip', 'blue'), ('strip', 'green'), ('strip', 'red')]]
func_g = [ggg, [('strip', 'grey'), ('strip', 'dk_red'), ('strip', 'dk_blue')]]

p = {'0': func_f, '1': func_g}

然后你可以用

构建一个选项 menu
options = '\n'.join('{} - {}'.format(k, v[0].__name__) for k,v in p.items())
which = input('Which?\n' + options + '\n')

然后你会选择并调用这样的函数。请注意*args,星号解压缩列表或元组中的多个项目。

func, calls = p[which]
for args in calls:
    func(*args)

>>> 
Which?
1 - ggg
0 - fff
1
g strip grey
g strip dk_red
g strip dk_blue
>>>

如果使用太多或太少的函数参数构造字典,则在调用函数时会抛出TypeError异常。如果用户提交无效选项,您将收到KeyError异常。 Handling Exceptions

与您在示例中使用的简单条件相比,这看起来有点复杂但如果您有很多函数,这可能会更好,这使您可以在运行时使用不同的参数值构造/修改字典。

f_calls = operator.itemgetter(1)
f_calls(func_f).append(('strip', 'hazel'))
f_calls (func_g)[0] = ('strip', 'maroon')

pprint(p)

>>>
{'0': [<function fff at 0x000000000312C048>,
       [('strip', 'blue'),
        ('strip', 'green'),
        ('strip', 'red'),
        ('strip', 'hazel')]],
 '1': [<function ggg at 0x0000000003165268>,
       [('strip', 'maroon'),
        ('strip', 'dk_red'),
        ('strip', 'dk_blue')]]}
>>>

这不是很通用,似乎它可以封装在一个类中。我敢打赌,这是一个非常普遍的事情,如果你在别人周围搜索,我会想出一些更精致的东西。

可能的改进是使用collections.namedtuple使其更具可读性。

Task = collections.namedtuple('Task', ['func', 'calls'])
task_f = Task(fff, [('strip', 'blue'), ('strip', 'green'), ('strip', 'red')])
task_g = Task(ggg, [('strip', 'grey'), ('strip', 'dk_red'), ('strip', 'dk_blue')])

p = {'0': task_f, '1': task_g}
options = '\n'.join('{} - {}'.format(item, task.func.__name__) for item,task in p.items())

which = input('Which?\n' + options + '\n')

task = p[which]
for args in task.calls:
    task.func(*args)


task_f.calls.append(('strip', 'candycane'))
task_g.calls.remove(('strip', 'grey'))