4

我最近才开始学习 Python。让我解释一下我要完成的工作。我有这个 .py 脚本,它基本上有几个函数(硬编码到脚本中),都需要添加到一个列表中,这样我就可以通过简单地使用索引运算符来获得我需要的函数,如下所示:

需要函数 = 函数列表[需要函数索引]

我第一次尝试实现这一点导致了以下代码结构:

(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() 将不包含这些函数,因为它们尚未定义。

也许我应该简单地满足于一个不太优雅的解决方案,或者也许我没有以惯用的方式编写我的脚本。无论如何,任何输入和建议都将受到赞赏。

4

3 回答 3

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:你也在尝试优化奇怪的东西,你最好只在文件中维护一个列表。您添加功能的频率是多少,并且很少考虑?在源文件中更新列表并不难。

于 2012-06-22T21:23:55.370 回答
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]()
于 2012-06-22T21:29:24.070 回答
0

解决此问题的一种方法是将所有这些函数放入一个容器中,然后从容器中提取函数以构建您的列表。

最 Pythonic 的容器是class. 我并不是说要让它们成为类的成员函数。只需在类中定义它们。

class MyFunctions(object):
    def func0():
        pass
    def func1():
        pass

lst_funcs = [x for x in MyFunctions.__dict__ if not x.startswith('_')]

但我更喜欢装饰器方法;这可能是最 Pythonic 的解决方案。

于 2012-06-22T21:28:38.067 回答