python中def中def是如何實現的?

比如這段代碼

每次調用f,內部的函數都會重新覆蓋定義一遍嗎?這豈不是要慢很多?不嵌套定義會顯得很難看,有什麼好的方法嗎?

另外python絕對不是單純地按行解釋運行,第一行input第二行出現語法錯誤會在一開始就(而不是按回車後)報錯,應該經過了詞法分析。


這要看你怎麼理解「定義」

其實py的作法是:

先編譯整段代碼,每個函數的代碼部分弄成一個code對象

然後執行def這句的時候,把code對象和當時一些信息打包一個func對象,賦值給f1code對象是唯一的,但func對象是實時生成的


從技術上講,當 Python 分析完這個函數的時候,嵌套的 def 會成為函數 f 的內部成員,只是沒有公開出來。運行到內部 def f1() 語句所做的工作就是把已定義的內部成員綁定到局部變數 f1 上,這個操作是很快的,不用擔心重複解析的問題。

你在代碼里加一個跟蹤語句,就可以看到這個函數的內部表示,比如:

def f(n):
if n &< 0: def f1(n): print(-n) print(locals after f1, locals()) f1(n) elif n == 0: def f2(n): print(0) print(locals after f2, locals()) f2(n) elif n &> 0:
def f3(n):
print(n)
print(locals after f3, locals())
f3(n)
else:
assert 0


答案是:會重新定義一遍

首先,你猜的很對,.py 源文件會在第一次執行的時候編譯為 .pyc 位元組碼文件,進行了初步的詞法分析。

那到底會不會在每次調用 f 的時候都重新定義內部函數呢

看下面的代碼

def f(n):
if n &< 0: def f1(n, set=[]): set.append(n) print(set) f1(n) f(-1) f(-2)

運行結果是

這是什麼意思呢?

因為 Python 的函數本身也是一個對象,函數的默認參數是它的成員

所以如果默認參數是 可變類型(或者說引用類型),而且你在函數中改變了它,如

def f(n, set = []):
set.append(n)
print(set)

f(-1)
f(-2)

就會出現:

所以很顯然,f 會在每次調用的時候重新定義內部函數

表現在 f1 的默認參數沒有發生變化

雖然你擔心這可能會有性能問題,但 Python 毫不在意......(傲嬌


請看cpython的源碼

函數在編譯的時候就會被編譯為pyfunc對象

然後儲存在常量池

重新定義只是執行位元組碼

LOAD_CONST x(&

WRITE_NAME x(namexxx)

而已

更正:


(自答)大家自行感受奇妙的結果吧(不妨多複製幾行,但輸出的地址我只看到三個)

def f(n):
def g():
pass
if n:
print(g,"print in f")
else:
return g

f(1)
f(1)
f(1)

a = f(0);print(a,"a")
a = f(0);print(a,"a")
a = f(0);print(a,"a")

b = f(0);print(b,"b")
b = f(0);print(b,"b")
b = f(0);print(b,"b")

print(f(0),"f(0)")
print(f(0),"f(0)")
print(f(0),"f(0)")

print(=*10)

f(1)
f(1)
f(1)

a = f(0);print(a,"a")
a = f(0);print(a,"a")
a = f(0);print(a,"a")

b = f(0);print(b,"b")
b = f(0);print(b,"b")
b = f(0);print(b,"b")

print(f(0),"f(0)")
print(f(0),"f(0)")
print(f(0),"f(0)")


這這...雖然我也是學語言的,但不是二進位語言啊,是自然語言.....所以愛莫能助了...


呃,這個雖然我也很想幫助您,奈何本人只是學c的。


你先定義好這些函數,建立起它們和n的映射,然後使用就好了。

具體可以把它們放到字典里,作為值。或者定義一個類,作為類的方法。

根據n大小dispatch用二分法,if else語句塊多了很醜。


推薦閱讀:

Julia快速入門(上)
會一門C語言、Bash語言和linux系統和計算機系學生差多少?
R語言學習第一章
為啥QT creater發布exe如此麻煩?

TAG:Python | 解釋器 | 編譯原理 | 計算機語言 |