无法通过管道命令访问django shell中的导入函数?

时间:2017-08-25 04:10:03

标签: python django shell

这是一个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

a similar question

2 个答案:

答案 0 :(得分:4)

我已经看了shell命令的代码。这是:

if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
    exec(sys.stdin.read())
    return

问题来自调用exec命令而不传递globalslocals参数,然后默认情况下,当前范围的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()