我看了一下shell
命令的代碼。那就是:
if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
exec(sys.stdin.read())
return
的問題來自於exec命令調用時沒有經過globals
和locals
參數,則默認情況下,將使用當前範圍的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
的擡頭,這是肯定不存在,所以csv
在globals()
字典中擡起頭來。但正如我上面寫的,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(), {})
希望這有助於你和我抱歉不能說明問題更短。
試試'cat | python manage.py shell'並在解釋器加載後粘貼相同的代碼..我真的不知道這個管道是否適用於manage.py – geckos
我的猜測是,Django沒有正確地將輸入重定向到shell進程 – geckos
'cat | python'也失敗了。 – sih4sing5hog5