>>> 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可能支持功能定義目標中的類似靈活性。 –