这是一个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
答案 0 :(得分: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()
dict与globals()
dict相同,那么这也将在globals()
dict中。但是,在我们的情况下,csv
仅在locals()
字典中,而不在globals()
字典中。
下一步:
def li2ho2():
print(csv)
当调用命令print(csv)
时,csv
将在函数locals()
的{{1}}字典中查找,并且它肯定不存在,所以在li2ho2
词典中查找csv
。但正如我上面所写,globals()
不在csv
词典中,这就是错误:globals()
被提出的原因。
我尝试更改tshi3.py的代码,如下所示:
NameError: name 'csv' is not defined
以两种不同的方式运行它:
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
希望这对您有所帮助,我很抱歉无法解决问题。
答案 1 :(得分:2)
如here所述-manage.py shell命令将globals()和locals()分开。因此,如果需要变量可见性的预期行为,则应使用新导入的局部变量手动更新全局变量列表。下面的方法比更改manage.py shell函数更容易:
import csv
globals().update(locals())
def li2ho2():
print(csv)
li2ho2()