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

标签 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

最佳答案

我看过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() 字典与 globals() 字典相同,这也将在 globals() 字典中。但是,在我们的例子中,csv 仅在 locals() 字典中,而不在 globals() 字典中。

下一步:

def li2ho2():
    print(csv)

当命令 print(csv) 被调用时,csv 将在函数 locals() 字典中查找>li2ho2,它肯定不存在,因此在 globals() 字典中查找 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/

相关文章:

python - python内置类型的比较排序

python - 我想每天上午 11 点发送电子邮件

linux - 用于循环和删除的 Shell 脚本

python - For 循环意外行为

python - 定点运算

django - 如何删除 Flutter 中的 "XMLHttpRequest error"? (Django 后端,Flutter 前端)

python - 渲染计数器集合排序顺序

.net - 从 .NET 应用程序执行 shell 命令

linux - 我可以在终端中执行文本文档中编写的命令吗

python - Python 列表、集合或字典是否可以使用数据库无形地实现?