我试图通过显示列表并要求用户选择列表中项目的索引来调用python 2.7中的函数。我对两点感到困惑:
用户输入的索引如何对应于初始列表中定义的功能?我了解如何选择列表中的项目,但不了解如何调用函数。
我应该把这段代码放在哪里?在主要功能?
这是我的代码:谢谢
''' 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))
答案 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}
然后你可以用
构建一个选项 menuoptions = '\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'))