>>> list=[None]
>>> def list[0](x,y):
File "<stdin>", line 1
def list[0](x,y):
^
SyntaxError: invalid syntax
如何将函数定义为列表元素?将函数定义为列表元素
>>> list=[None]
>>> def list[0](x,y):
File "<stdin>", line 1
def list[0](x,y):
^
SyntaxError: invalid syntax
如何将函数定义为列表元素?将函数定义为列表元素
Python的def
不够灵活,无法处理通用lvalues,如list[0]
。该语言只允许您使用标识符作为函数名称。下面是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在列表:
def f(whatever):
do_stuff()
l[0] = f
函数定义语法不允许您直接定义一个函数到数据结构,但你可以创建功能,那么无论它需要去指定。
或'l = []; l.append(f)' – SethMMorton
@SethMMorton:或者只是'l = [f]'如果你正在控制'l'的创建,而不是试图将函数分配到现有的位置,但我认为这会更清晰。 – user2357112
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)
允许这样的自由将使解析较硬的......例如括号表达式
...(x, y, z=3)
可以是参数声明(其中3
为关键字参数z缺省值)或呼叫(即传递z
关键字参数值作为3
)。
如果你想允许def
通用分配表示你还需要允许
def foo(x, y, z=3)[3](x, y, z=3):
...
,其中第一个括号部分具有从第二部分不同的语义和语法规则。
为此编写一个解析器很烦人(基本上是因为你需要处理一个任意的无限量的源代码而不理解它),这就是例如导致我知道的整个宇宙中最差的解析规则(这是可怕的C++的most vexing parse),基本上放弃了试图通过辞退歧义来获得体面的语言。
请注意,在很多情况下,当程序难以进行解析时,这是因为含糊不清,会让人难以理解它。
Python正确地将可读性看作非常重要。在Python
函数是但第一类对象,所以你可以解决你的问题很容易就够了:
def foo(...):
...
mylist[index] = foo
或者,只有当函数是一个单一的表达,与
mylist[index] = lambda ... : ...
(但lambda
是非常有限的,这既是因为它在Python社区中有点“讨厌”,也因为它会在语法级别造成一些烦恼,因为需要处理括号内的缩进)。
还要注意,一些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):
...
你是完全正确的,但是,我必须对这样一个复杂的事情是必要的事实咆哮。有一个非常好的语法元素:装饰器。他们可以很容易地用于此。我有时做的是返回或产生一个函数,但装饰器不适用于语句。然而,'@ return'或'@ yield'应该是相当不错的。在这种情况下,我们可以在这之前有一个'@ = target'(因为分配目标位于右边而会变得丑陋),或者'@@ target',比如'@@ global_register ['http']'函数,在函数之后不需要丑陋的赋值/产量/返回行。 – glglgl
@glglgl:你可以做比使用'@register('http')''等参数化装饰器更简单的事情。他们有点奇怪的实现(参数化装饰器必须返回一个非参数化的装饰器函数),但他们很好用。请参阅编辑。 – 6502
对,在这种情况下,这是一个不错的选择;我忘了那个。但是,唉,不能用于简化“yield”或“return”之类的东西。 – glglgl
你到底想干什么?我认为你想要的是你不应该做的事情,但即使如此,我不知道你在问什么 – TerryA
为什么这么多用户低估了这个合法的问题让我印象深刻。 – Hyperboreus
这是一个完全合法的问题。其他一些语言确实允许通用的左值(不仅仅是标识符)作为函数定义的目标。 OP合理地认为Python可能支持功能定义目标中的类似灵活性。 –