这是一个 python 脚本 tshi3.py
:
import csv
def li2ho2():
print(csv)
li2ho2()
我复制了这段代码并将其粘贴到 python manage.py shell
中。
它有效。
但我运行了 python manage.py shell < tshi3.py
。
得到 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
最佳答案
我看过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()
字典中查找>li2ho2globals()
字典中查找 csv
。但是正如我上面写的,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
因此,您可以看到它与我上面解释的完全一样。这个问题可以通过为 exec
命令传递一个空字典作为 globals
参数来解决,如下所示:
exec(sys.stdin.read(), {})
希望这对您有所帮助,很抱歉无法更简短地解释问题。
关于python - 无法通过管道命令访问 django shell 中的导入函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45874321/