Pythonic,优雅的方式动态定义静态定义的函数列表?

时间:2012-06-22 21:19:47

标签: python dynamic scripting static

我最近才开始学习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()不会包含函数,因为它们尚未定义。

也许我应该只是满足于一个不那么优雅的解决方案,或者我可能不会以惯用的方式编写我的脚本。无论如何,任何意见和建议都会受到赞赏。

3 个答案:

答案 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('_')]

但我更喜欢装饰师的做法;这可能是最恐怖的解决方案。