我最近才开始学习Python。让我解释一下我想要实现的目标。我有这个.py脚本基本上有几个函数(硬编码到脚本中),所有这些函数都需要添加到一个列表中,这样我就可以通过简单地使用索引运算符获得我需要的函数,如下所示: p>
needed_function = function_list [needed_function_index]
我首次尝试实现此功能导致以下代码结构:
(imports)
function_list = []
(other global variables)
def function_0 = (...)
function_list.append(function_0)
def function_1 = (...)
function_list.append(function_1)
def function_2 = (...)
function_list.append(function_2)
(rest of code)
但我不喜欢这个解决方案,因为它不是很优雅。我的目标是能够简单地将函数定义添加到脚本中(没有追加调用),脚本会自动将其添加到函数列表中。
我已经考虑过定义另一个功能中的所有功能,但我不认为我可以随意使用这些功能。我想到了可能"标记"每个函数都有一个装饰器,但我意识到每次调用一个函数时都会调用装饰器(如果我理解正确的话),而不是只调用一次。
过了一段时间我想出了这个解决方案:
(imports)
(global variables)
def function_0 = (...)
def function_1 = (...)
def function_2 = (...)
function_list= [globals()[x] for x in globals() if re.match('^function_[0-9]+$', x)]
(rest of code)
我更喜欢它作为一种解决方案,但我唯一的理由是,出于清洁的目的,我宁愿在脚本的顶部完全定义function_list。但是,我不能这样做,因为在脚本顶部调用globals()不会包含函数,因为它们尚未定义。
也许我应该只是满足于一个不那么优雅的解决方案,或者我可能不会以惯用的方式编写我的脚本。无论如何,任何意见和建议都会受到赞赏。
答案 0 :(得分:8)
你错了装饰者。它们在定义函数时被调用一次,它们返回的函数就是赋值给函数名的值,它是每次调用的函数。您可以在装饰器中执行您想要的操作,而不会产生运行时开销。
my_functions = []
def put_in_list(fn):
my_functions.append(fn)
return fn
@put_in_list
def function1():
pass
@put_in_list
def function2():
pass
PS:无论如何,您可能不需要担心运行时开销。
PPS:你也在尝试优化奇怪的东西,你可能最好只是在文件中维护一个列表。您多久添加一次功能,并且思考的程度如何?在源文件中更新列表并不困难。
答案 1 :(得分:1)
使用不向函数调用添加任何开销的装饰器的示例:
my_list = []
def add_to_my_list(func):
print 'decorator called'
my_list.append(func)
return func
@add_to_my_list
def foo():
print 'foo called'
@add_to_my_list
def bar():
print 'foo called'
print '-- done defining functions --'
my_list[0]()
my_list[1]()
答案 2 :(得分:0)
解决此问题的一种方法是将所有这些函数放入一个容器中,然后从容器中提取函数以构建列表。
最Pythonic容器是class
。我不是说要让它们成为班级的成员;只需在课堂上定义它们。
class MyFunctions(object):
def func0():
pass
def func1():
pass
lst_funcs = [x for x in MyFunctions.__dict__ if not x.startswith('_')]
但我更喜欢装饰师的做法;这可能是最恐怖的解决方案。