2014-01-21 43 views
17

最近,我開始好奇,但在下面的僞Python代碼的第2行,會發生什麼:如果你在python中單獨編寫變量名稱,會發生什麼?

def my_fun(foo,bar): 
    foo 
    return foo + bar 

我很感興趣的原因是,我想光表,並試圖把手錶上的「福。 「它似乎導致python解釋器掛起。

我正確的認爲這條線絕對沒有影響,不會造成任何形式的錯誤?有人可以解釋解釋者到底在做什麼嗎?

回答

27

我們可以看一下與從內置dis模塊一點幫助發生:

import dis 

def my_fun(foo,bar): 
    foo 
    return foo + bar 

dis.dis(my_fun) 

dis.dis功能拆卸功能(是的,它可以拆卸本身),方法和類。

dis.dis(my_fun)輸出是:

4   0 LOAD_FAST    0 (foo) 
       3 POP_TOP 

    5   4 LOAD_FAST    0 (foo) 
       7 LOAD_FAST    1 (bar) 
      10 BINARY_ADD 
      11 RETURN_VALUE 

前兩個字節碼是正是我們需要的:在foo線。

下面是這些字節碼做:

  1. 第一個推到一個局部變量foo參考入堆棧 (LOAD_FAST
  2. 第二個移除堆棧頂部(POP_TOP

基本上,foo行不起作用。 (當然,如果沒有則定義foo變量LOAD_FAST會拋出NameError

4

在命令行嘗試它:它只返回foo中的值。 這並不意味着它不能在某些特殊情況下的副作用:如果你做這樣的事情:

def my_fun(foo, bar): 
    foo.prop 
    return foo.func(bar) 

即使在技術上我們剛剛返回的值,如果它定義爲一個屬性,則可以foo.prop實際上調用一個函數。

但通常情況下......你不會在模塊中這樣做,只能在交互式控制檯中進行。

9

什麼也沒有發生。它成爲等同於毫無意義的操作 望着dis輸出

In [3]: dis.dis(my_fun) 
    2   0 LOAD_FAST    0 (foo) 
       3 POP_TOP    

    3   4 LOAD_FAST    0 (foo) 
       7 LOAD_FAST    1 (bar) 
      10 BINARY_ADD   
      11 RETURN_VALUE 

我們可以看到,它的負載快foo然後什麼都不做吧。

+1

+ 1,我不知道'dis' –

1

什麼也沒有發生:

>>> def baz(foo, bar): 
    foo 
    return bar 

>>> baz(10, 20) 
20 

聲明沒有任何效果。

+3

雖然你的結論是正確的,但你的論點是假的。僅僅因爲它在你找到的一種情況下什麼都不做,並不意味着它在任何情況下都不會做任何事情。 – Cruncher

2

foo語句是expression statement的一個示例,因此在解釋器遇到它時會進行評估。

表達式語句計算表達式列表(可能是一個 單個表達式)。

foo所以被加載,表達式求值(這是foo本身,因此不需要進一步的動作),並且結果被立即被遺忘。

相關問題