当 运行 和 manage.py 时 ThreadPoolExecutor 失败
ThreadPoolExecutor fails when run with manage.py
# 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
命令导致 time
模块在函数 a
中未定义的脚本是什么?
我认为它不起作用,因为您没有将环境变量 DJANGO_SETTING_MODULE
设置为您的设置,并调用 django.setup()
或将路径设置为 sys.path.append('path/' )
(不确定)
但这 2 个选项可以起到很好的作用:
要么在函数中导入模块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()
检查 Django 实现(django/core/management/commands/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()'字典中导入时间和ThreadPoolExecutor (在 shell.py 中)但是之后,当您尝试在 a()
内部使用时,它会尝试在 "a" 范围的 locals()
字典和 globals()
中搜索字典所以它会抛出一个导入错误,你可以在这个片段中看到一个例子:
command = """
import time
def b():
time.sleep(1)
b()
"""
def a():
exec(command)
a()
并尝试将 exec(command)
更改为 exec(command, globals())
# 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
命令导致 time
模块在函数 a
中未定义的脚本是什么?
我认为它不起作用,因为您没有将环境变量 DJANGO_SETTING_MODULE
设置为您的设置,并调用 django.setup()
或将路径设置为 sys.path.append('path/' )
(不确定)
但这 2 个选项可以起到很好的作用:
要么在函数中导入模块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()
检查 Django 实现(django/core/management/commands/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()'字典中导入时间和ThreadPoolExecutor (在 shell.py 中)但是之后,当您尝试在 a()
内部使用时,它会尝试在 "a" 范围的 locals()
字典和 globals()
中搜索字典所以它会抛出一个导入错误,你可以在这个片段中看到一个例子:
command = """
import time
def b():
time.sleep(1)
b()
"""
def a():
exec(command)
a()
并尝试将 exec(command)
更改为 exec(command, globals())