将函数定义为列表元素

时间:2013-08-04 06:04:06

标签: python

>>> list=[None]
>>> def list[0](x,y):
  File "<stdin>", line 1
    def list[0](x,y):
             ^
SyntaxError: invalid syntax

如何将函数定义为列表元素?

4 个答案:

答案 0 :(得分:10)

Python的def不够灵活,无法处理list[0]等通用lvalues。该语言仅允许您使用标识符作为函数名称。以下是grammar rule for the def-statement的相关部分:

funcdef        ::=  "def" funcname "(" [parameter_list] ")" ":" suite
funcname       ::=  identifier

相反,您可以使用一系列赋值和定义语句:

s = [None]

def f(x, y):
    return x + y

s[0] = f

作为替代方案,您还可以将lambda expression直接存储在列表中:

s = [lambda x,y : x+y]

答案 1 :(得分:9)

def f(whatever):
    do_stuff()

l[0] = f

函数定义语法不允许您直接将函数定义到数据结构中,但您可以创建函数,然后将其分配到需要的位置。

答案 2 :(得分:4)

def someFunctionA(x, y):
    return x+y

def someFunctionB(x, y):
    return x*y

someList = [someFunctionA, someFunctionB]

print someList[0](2, 3)
print someList[1](5, 5)

答案 3 :(得分:2)

允许这样的自由会使解析变得更难......例如带括号的表达式

...(x, y, z=3)

可以是参数声明(其中3是关键字参数z的默认值)或调用(将z关键字参数值传递为3)。

如果您想在def中允许通用的可指定表达式,则还需要允许

def foo(x, y, z=3)[3](x, y, z=3):
    ...

其中第一个带括号的部分具有不同的语义含义和第二部分的语法规则。

为此编写解析器很烦人(主要是因为你需要处理任意无限量的源代码而不理解它)并且例如导致我知道的整个宇宙中最糟糕的解析规则(这是可怕的{ C ++的{3}}基本上只是放弃试图通过辞职来获得一种体面的语言。

请注意,在许多情况下,当程序更难以进行解析时,由于模糊不清会使人们更难理解它。

Python正确地将可读性视为非常重要。

Python中的函数是一流的对象,因此您可以轻松地解决问题:

def foo(...):
    ...

mylist[index] = foo

或者,仅当函数是单个表达式时,使用

mylist[index] = lambda ... : ...

(但是lambda非常有限,因为它在Python社区中有点“讨厌”,也因为它需要在括号内处理缩进,因此会在语法级别产生一些烦恼。 / p>

另请注意,一些Python新手不知道的是,即使在函数内部也可以使用def;例如:

def register_http():
    def handle_http(connection):
        ...
    global_register['http'] = handle_http

将函数指定为全局映射的元素,而不会使用其名称来污染全局(模块)命名空间。本地def也可以通过捕获本地状态变量(2.x中的只读,甚至3.x中的读/写)来创建闭包。

另请注意,如果您需要某个函数的某些处理,decorators可能会有用。例如,通过定义

def register(name):
    def do_registering(f):
        global_register[name] = f
        return f
    return do_registering

你可以使用

@register('http')
def handle_http(connection):
    ...