2017-09-03 56 views
1

我有一個爲其定義next方法的類。當我從創建該類的對象的命令行運行腳本並運行以下循環來調用next時,將不會打印next的返回值,但是當我從Python控制檯運行相同的行時,會返回值。當從Python Shell,IPython控制檯以及從腳本內部運行時,下一個函數的不同行爲

更具體地講,如果我們將以下腳本保存爲tests.py

class Solution(): 
    def __next__(self): 
     return 1 

s = Solution() 
for _ in range(5): 
    next(s) 

和運行python test.py,沒有打印(我測試了這個關於Python 3.4和Windows機器)。

然而,如果我們作爲一個Python外殼下面,輸出將被打印:

(python34) C:\>python 
Python 3.4.5 |Anaconda custom (64-bit)| (default, Jul 5 2016, 14:53:07) [MSC 
v.1600 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> class Solution(): 
...  def __next__(self): 
...   return 1 
... 
>>> s = Solution() 
>>> for _ in range(5): 
...  next(s) 
... 
1 
1 
1 
1 
1 

在IPython的控制檯還沒有輸出打印。

+0

我以爲我知道..結果我不太清楚。我的答案中記錄的行爲僅在IPython中觀察到,而不是標準的IDLE。所以,我會刪除我的答案。 –

+0

你如何運行這些代碼?你是用python控制檯,ipython還是命令行來運行它?我認爲你所看到的取決於你如何運行它。你還可以用簡化的形式包括'Solution'類嗎? – nos

+0

是的,我也注意到這個行爲實際上取決於你在@ COLDSPEED之後如何運行代碼。只要有機會,我會盡快更新信息。它與temp變量沒有任何關係。 –

回答

1

您可以看到here IPython一次一個地運行ast節點,而不是一次全部運行,您可以更改IPython運行節點的方式,但默認情況下它只會在AST的最後一個根節點上觸發顯示副作用。如果您有for循環,則「next()」節點不是最後一個根節點,「for」是,並且它不返回任何值(它不是表達式的語句)。這是故意不要壓倒筆記本上的用戶。

我的猜測是,這是比Python的REPL做什麼語義不同,在純Python REPL無論是跑跑交互的最後節點,或所有,我不記得了。

您可以檢查Python的REPL確實有簡單的例子是什麼:你不需要Solution類,你可以用任何表情,這不工作做到這一點:

>>> for i in range(5): 
...  i # try adding more expressions like i**2 on another line 
... 
0 
1 
2 
3 
4 

,你可以得到相同的行爲在IPython的一個標誌:

$ ipython --TerminalInteractiveShell.ast_node_interactivity=all 
Python 3.6.1 | packaged by conda-forge | (default, May 23 2017, 14:31:56) 
Type 'copyright', 'credits' or 'license' for more information 
IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help. 

In [1]: for i in range(5): 
    ...:  i 
    ...: 
Out[1]: 0 
Out[1]: 1 
Out[1]: 2 
Out[1]: 3 
Out[1]: 4 

我個人喜歡的last_expr_or_assign值,使最後的任務返回分配的值:

$ ipython --TerminalInteractiveShell.ast_node_interactivity = last_expr_or_assign

Python 3.6.1 |由conda-forge |包裝(默認,2017年5月23日,14:31:56) 輸入'copyright','credits'或'license'以獲取更多信息 IPython 6.2.0.dev - 增強型交互式Python。鍵入'?'求助。

In [1]: a = 1 # No Out 
    ...: b = 2 # Out will be 2. Useless here, 
    ...:  # but nice if you do `df = pd.load_csv(...)` 
Out[1]: 2 
+0

謝謝。 「last_expr_or_assign」值只是iPython 6.2的一個特性,因爲在iPython 6.1中,它似乎不可用。 –

+0

當我們以類似的方式在交互模式下調用Python時,我們是否也可以控制Python(例如CPython)的行爲?當我在這裏搜索https://docs.python.org/3/using/cmdline.html我找不到任何標誌。 –

+0

我不認爲你可以控制Python的。另外它是IPython大寫字母I,不想惹惱水果公司:-) – Matt