# test.py
# python 3.4.5
import time
from concurrent.futures import ThreadPoolExecutor
def a():
time.sleep(1)
print("success")
executor = ThreadPoolExecutor(1)
executor.submit(a).result()
上面的代码片段在运行时有效
$ python test.py
success
但运行时失败
$ python manage.py shell < test.py
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/var/www/cgi-bin/tracking/lib64/python3.4/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
utility.execute()
File "/var/www/cgi-bin/tracking/lib64/python3.4/site-packages/django/core/management/__init__.py", line 355, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/var/www/cgi-bin/tracking/lib64/python3.4/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/var/www/cgi-bin/tracking/lib64/python3.4/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/var/www/cgi-bin/tracking/lib64/python3.4/site-packages/django/core/management/commands/shell.py", line 101, in handle
exec(sys.stdin.read())
File "<string>", line 11, in <module>
File "/usr/lib64/python3.4/concurrent/futures/_base.py", line 395, in result
return self.__get_result()
File "/usr/lib64/python3.4/concurrent/futures/_base.py", line 354, in __get_result
raise self._exception
File "/usr/lib64/python3.4/concurrent/futures/thread.py", line 54, in run
result = self.fn(*self.args, **self.kwargs)
File "<string>", line 7, in a
NameError: name 'time' is not defined
这对我来说真的很奇怪。使用manage.py shell
命令运行脚本会导致函数a
中未定义time
模块是什么?
检查 Django 实现(django/core/management/command/shell.py第 83 行(:
# Execute stdin if it has anything to read and exit.
# Not supported on Windows due to select.select() limitations.
if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
exec(sys.stdin.read())
return
开发人员没有在exec()
方法中添加globals()
范围,这意味着您将在handle()
范围的"locals(("字典(shell.py(中导入时间和 ThreadPoolExecutor,但之后,当您尝试在a()
中使用时,它会尝试在"a"范围的locals()
字典和globals()
字典中搜索,因此它会抛出导入错误, 您可以在此代码段中看到一个示例:
command = """
import time
def b():
time.sleep(1)
b()
"""
def a():
exec(command)
a()
并尝试通过exec(command, globals())
来改变exec(command)
我认为它不起作用,因为您没有将环境变量DJANGO_SETTING_MODULE
设置为您的设置,并调用django.setup()
或将路径设置为 sys.path.append('path/'(
(不确定(
但是这两个选项可以像魅力一样工作:
要么在函数内部导入模块time
:
from concurrent.futures import ThreadPoolExecutor
def a():
import time
time.sleep(1)
print("success")
executor = ThreadPoolExecutor(1)
executor.submit(a).result()
或者像你一样在开始时import time
,并将该模块用作global
模块:
from concurrent.futures import ThreadPoolExecutor
import time
def a():
global time
time.sleep(1)
print("success")
executor = ThreadPoolExecutor(1)
executor.submit(a).result()