2017-08-25 50 views
0

這是一個Python腳本tshi3.py無法通過管道命令訪問django shell中的導入函數?

import csv 
    def li2ho2(): 
     print(csv) 
    li2ho2() 

我複製此代碼,並在python manage.py shell粘貼它。 它的工作原理。

但我跑了python manage.py shell < tshi3.py。 Got NameError: name 'csv' is not defined

爲什麼?

環境:

Linux Mint 18.1 
    Python 3.4.1 (default, Sep 3 2014, 08:45:22) 
    Django==1.11.4 

a similar question

+0

試試'cat | python manage.py shell'並在解釋器加載後粘貼相同的代碼..我真的不知道這個管道是否適用於manage.py – geckos

+0

我的猜測是,Django沒有正確地將輸入重定向到shell進程 – geckos

+0

'cat | python'也失敗了。 – sih4sing5hog5

回答

1

我看了一下shell命令的代碼。那就是:

if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]: 
    exec(sys.stdin.read()) 
    return 

的問題來自於exec命令調用時沒有經過globalslocals參數,則默認情況下,將使用當前範圍的globals()locals()字典。請注意,在模塊級別,globals和locals是相同的字典,但在當前作用域(在django.core.management.commands.shell.Command.handle處),globals()和locals()是兩個不同的字典。現在,當執行tshi3.py的代碼時,事情變得無法控制。

讓我們通過每一行代碼:

import csv 

這將導入模塊csv,並把它放到locals()字典。所以,如果locals()字典與globals()字典相同,這也將在globals()字典中。但是,在我們的例子中,csv僅在locals()字典中,而不在globals()字典中。

下一頁:

def li2ho2(): 
    print(csv) 

當命令print(csv)被調用時,csv將在locals()詞典功能li2ho2的擡頭,這是肯定不存在,所以csvglobals()字典中擡起頭來。但正如我上面寫的,csv不在globals()字典中,這就是爲什麼錯誤:NameError: name 'csv' is not defined被引發。

我嘗試改變tshi3.py的代碼如下:

import csv 

print('globals() equals to locals(): {}'.format(globals() == locals())) 
print('csv is in globals(): {}'.format('csv' in globals())) 
print('csv is in locals(): {}'.format('csv' in locals())) 

def li2ho2(): 
    print('inside li2ho2 function:') 
    print(' csv is in globals(): {}'.format('csv' in globals())) 
    print(' csv is in locals(): {}'.format('csv' in locals())) 

li2ho2() 

,並在兩個不同的方式運行:

$ python tshi3.py 
globals() equals to locals(): True 
csv is in globals(): True 
csv is in locals(): True 
inside li2ho2 function: 
    csv is in globals(): True 
    csv is in locals(): False 

$ ./manage.py shell < tshi3.py 
globals() equals to locals(): False 
csv is in globals(): False 
csv is in locals(): True 
inside li2ho2 function: 
    csv is in globals(): False 
    csv is in locals(): False 

所以,你可以看到它的正是正如我上面所解釋。這個問題可以通過固定傳遞一個空字典爲globals參數,如下exec命令:

exec(sys.stdin.read(), {})

希望這有助於你和我抱歉不能說明問題更短。