私はshell
コマンドのコードを見てきました。ここでは、次のとおりです。
if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
exec(sys.stdin.read())
return
問題は、EXECコマンドから来ているが、globals
とlocals
パラメータを渡さずに呼び出され、デフォルトで、現在のスコープのglobals()
とlocals()
辞書が使用されます。
モジュールレベルでは、グローバルとローカルは同じ辞書ですが、現在のスコープ(django.core.management.commands.shell.Command.handle)では、globals()とlocals()は2つの異なる辞書。そして、tshi3.py
のコードが実行されると、制御不能になります。
のは、コードの各行見ていきましょう:
import csv
これは、モジュールcsv
をインポートして、locals()
辞書に入れます。したがって、locals()
dictがglobals()
dictと同じ場合は、これもglobals()
dictになります。私たちの場合、csv
はlocals()
dictでのみあり、globals()
dictではありません。
次へ:コマンドprint(csv)
が呼び出されると
def li2ho2():
print(csv)
、csv
は機能li2ho2
のlocals()
辞書で検索されます、そして、それはそこに確かではありませんので、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()
そして、2つの異なる方法でそれを実行します。
$ 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
だから、あなたはそれがまさに私が上記で説明したものとだ見ることができます。これはあなたを助け、私は短い問題を説明することはできないため、申し訳ありません
exec(sys.stdin.read(), {})
希望:この問題は、以下のようにexec
コマンドのglobals
パラメータとして空の辞書を渡すことによって固定することができます。
お試しくださいcat | python manage.py shell'を実行し、インタプリタがロードされたら同じコードを貼り付けます。この配管がmanage.pyで動作するかどうかは本当に分かりません。 – geckos
Djangoが入力をシェルプロセスに正しくリダイレクトしていないと思われます。 – geckos
'cat | python'も失敗しました。 – sih4sing5hog5