sih*_*og5 2 python django shell
这是一个python脚本tshi3.py:
import csv
def li2ho2():
print(csv)
li2ho2()
Run Code Online (Sandbox Code Playgroud)
我复制了这段代码并将其粘贴到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
Run Code Online (Sandbox Code Playgroud)
有一个类似的问题。
小智 5
我已经查看了shell命令代码。这里是:
if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
exec(sys.stdin.read())
return
Run Code Online (Sandbox Code Playgroud)
问题出在没有传递globalsandlocals参数的情况下调用 exec 命令,那么默认情况下,将使用当前作用域的globals()andlocals()字典。
请记住,在模块级别, globals 和 locals 是同一个字典,但在当前范围(在 django.core.management.commands.shell.Command.handle 处), globals() 和 locals() 是两个不同的字典。现在,当tshi3.py执行的代码时,事情变得无法控制。
让我们来看看每一行代码:
import csv
Run Code Online (Sandbox Code Playgroud)
这将导入模块csv并将其放入locals()字典中。因此,如果locals()dict与dict 相同globals(),则这也将在globals()dict 中。但是,在我们的例子中,csv只在locals()字典中,globals()不在字典中。
下一个:
def li2ho2():
print(csv)
Run Code Online (Sandbox Code Playgroud)
当命令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()
Run Code Online (Sandbox Code Playgroud)
并以两种不同的方式运行它:
$ 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
Run Code Online (Sandbox Code Playgroud)
所以,你可以看到它和我上面解释的完全一样。这个问题可以通过传递一个空字典作为命令的globals参数来解决exec,如下所示:
exec(sys.stdin.read(), {})
希望这对您有所帮助,我很抱歉无法更简短地解释问题。
正如这里所说的-manage.py shell命令分割globals()和locals()。因此,如果您需要变量可见性的预期行为,您应该使用新导入的局部变量手动更新全局变量列表。下面的方法比更改manage.py shell函数更容易:
import csv
globals().update(locals())
def li2ho2():
print(csv)
li2ho2()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
703 次 |
| 最近记录: |