Python 在芹菜任务中动态导入模块

Python 在芹菜任务中动态导入模块,python,celery,python-importlib,Python,Celery,Python Importlib,是否可以在芹菜任务中动态导入模块 例如,我的工作目录中有一个名为hello.py的模块: $ cat hello.py def run(): print('hello world') 我可以使用importlib动态导入它: $ python3 Python 3.5.2 (default, Jul 5 2016, 12:43:10) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "lice

是否可以在芹菜任务中动态导入模块

例如,我的工作目录中有一个名为
hello.py
的模块:

$ cat hello.py 
def run():
    print('hello world')
我可以使用
importlib
动态导入它:

$ python3
Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import importlib
>>> p = importlib.import_module('hello')
>>> p.run()
hello world
我想从芹菜任务中执行与上面相同的操作:

@celery.task()
def exec_module(module, args={}):
    print('celery task running: %s' % (module))
    print(args)
    print(os.getcwd())
    print(os.listdir())

    module = importlib.import_module('hello')
    module.run()
当任务运行时,我遇到以下错误:

[2016-09-11 17:51:48,132: WARNING/MainProcess] celery@user-HP-EliteBook-840-G2 ready.
[2016-09-11 17:52:05,516: INFO/MainProcess] Received task: web.tasks.exec_module[f24e3d03-5a17-41dc-afa9-541c99b60a35]
[2016-09-11 17:52:05,518: WARNING/Worker-1] celery task running: example_module
[2016-09-11 17:52:05,518: WARNING/Worker-1] {'example_file': '/tmp/tmpo4ks9ql0.xml', 'example_string': 'asd'}
[2016-09-11 17:52:05,518: WARNING/Worker-1] /home/user/Learning/vision-boilerplate
[2016-09-11 17:52:05,518: WARNING/Worker-1] ['run.py', 'requirements.txt', 'gulpfile.js', 'tsconfig.json', 'typings.json', 'package.json', 'vision_modules', 'typings', 'web', 'config', 'hello.py', 'docker-compose.yml', 'ng', 'node_modules', 'Dockerfile']
[2016-09-11 17:52:05,523: ERROR/MainProcess] Task web.tasks.exec_module[f24e3d03-5a17-41dc-afa9-541c99b60a35] raised unexpected: ImportError("No module named 'hello'",)
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/user/Learning/vision-boilerplate/web/__init__.py", line 21, in __call__
    return TaskBase.__call__(self, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/celery/app/trace.py", line 438, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/user/Learning/vision-boilerplate/web/tasks.py", line 19, in exec_module
    module = importlib.import_module('hello')
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named 'hello'
[2016-09-11 17:51:48132:警告/主流程]celery@user-HP-EliteBook-840-G2就绪。
[2016-09-11 17:52:05516:INFO/MainProcess]收到的任务:web.tasks.exec_模块[f24e3d03-5a17-41dc-afa9-541c99b60a35]
[2016-09-11 17:52:05518:警告/Worker-1]芹菜任务正在运行:示例_模块
[2016-09-11 17:52:05518:WARNING/Worker-1]{'example_file':'/tmp/tmpo4ks9ql0.xml','example_string':'asd'}
[2016-09-11 17:52:05518:警告/工人-1]/家庭/用户/学习/愿景样板
[2016-09-11 17:52:05518:WARNING/Worker-1]['run.py'、'requirements.txt'、'gulpfile.js'、'tsconfig.json'、'typings.json'、'package.json'、'vision_modules'、'typings'、'web'、'config'、'hello.py'、'docker compose.yml'、'ng'、'node_modules'、'Dockerfile']
[2016-09-11 17:52:05523:ERROR/MainProcess]任务web.tasks.exec_模块[f24e3d03-5a17-41dc-afa9-541c99b60a35]引发意外:导入错误(“没有名为“hello”的模块,)
回溯(最近一次呼叫最后一次):
文件“/usr/local/lib/python3.5/dist packages/芹菜/app/trace.py”,第240行,在trace_任务中
R=retval=fun(*args,**kwargs)
文件“/home/user/Learning/vision-boilerplate/web/_-init__.py”,第21行,在调用中__
返回TaskBase.\uuuu调用(self,*args,**kwargs)
文件“/usr/local/lib/python3.5/dist-packages/芹菜/app/trace.py”,第438行,在受保护的调用中__
返回self.run(*args,**kwargs)
文件“/home/user/Learning/vision-boilerplate/web/tasks.py”,第19行,在exec_模块中
module=importlib.import\u module('hello'))
文件“/usr/lib/python3.5/importlib/_init__.py”,第126行,在导入模块中
return _bootstrap._gcd_import(名称[级别:],包,级别)
文件“”,第986行,在_gcd_import中
文件“”,第969行,在“查找”和“加载”中
文件“”,第956行,在“查找”和“加载”中解锁
ImportError:没有名为“hello”的模块
请注意,
print(os.listdir())
(上面调试输出中的第6行)的输出表明,我们确实位于正确的目录中,
hello.py
就在那里

是否可以从芹菜任务中动态导入模块?2018-05-23更新:

在芹菜中,工作是由工人来完成的。默认情况下,多处理用于执行任务的并发执行

当worker调用任务函数时,我们当前的工作目录(os.getcwd())不在
sys.path
中,因此它找不到模块名

问题的根源可能是:当芹菜启动工作进程时,它没有复制当前进程的信息


是否可以在芹菜任务中动态导入模块

对。因为我已经做到了。 当模块是单个的并且不属于任何包时,您应该将模块的目录添加到sys路径

sys.path.append('模块的路径')

例如:

import importlib
import os
import sys
import celery
from demo import celeryconfig

# add your path to the sys path
sys.path.append(os.getcwd())

app = celery.Celery('tasks',)
app.config_from_object(celeryconfig)


@celery.task()
def exec_module(module, args={}):
    print('celery task running: %s' % (module))
    print(args)
    print(os.getcwd())
    print(os.listdir())

    module = importlib.import_module('hello')
    module.run()
我希望这对你有帮助。谢谢