gpt4 book ai didi

python - 并行: Import a python file from sibling folder

转载 作者:行者123 更新时间:2023-12-01 01:16:05 24 4
gpt4 key购买 nike

我有一个目录树

working_dir\
main.py
my_agent\
my_worker.py
my_utility\
my_utils.py

各文件中的代码如下

""" main.py """

import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from my_agent.my_worker import MyWorker
import ray

ray.init()
workers = [MyWorker.remote(i) for i in range(10)]
ids = [worker.get_id.remote() for worker in workers]
# print(*ids, sep='\n')
print(*ray.get(ids), sep='\n')
""" worker.py """
from my_utility import my_utils
import ray

@ray.remote
class MyWorker():
def __init__(self, id):
self.id = id

def get_id(self):
return my_utils.f(self.id)
""" my_utils.py """
def f(id):
return '{}: Everything is fine...'.format(id)

这是我收到的错误消息的一部分

Traceback (most recent call last):

File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/function_manager.py", line 616, in fetch_and_register_actor unpickled_class = pickle.loads(pickled_class)

File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/cloudpickle/cloudpickle.py", line 894, in subimport import(name)

ImportError: No module named 'my_utility'

Traceback (most recent call last):

File "main.py", line 12, in print(*ray.get(ids), sep='\n')

File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/worker.py", line 2377, in get raise value ray.worker.RayTaskError: ray_worker (pid=30025, host=AiMacbook)

Exception: The actor with name MyWorker failed to be imported, and so cannot execute this method

如果我删除所有与ray相关的语句,上面的代码就可以正常工作。因此,我大胆猜测原因是ray运行新进程中的每个参与者和 sys.path.append 只能在主进程中工作。所以我将以下代码添加到 worker.py

import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

但它仍然不起作用:出现相同的错误消息。现在我没有主意了,我该怎么办?

最佳答案

您对问题所在的理解是正确的。

在您的示例中,您修改 main.py 中的 sys.path 以便能够导入 my_agent.my_workermy_utility.my_utils.

但是,此路径更改不会传播到工作进程,因此如果您要运行像这样的远程函数

@ray.remote
def f():
# Print the PYTHONPATH on the worker process.
import sys
print(sys.path)

f.remote()

您会看到工作线程上的 sys.path 不包含您添加的父目录。

修改工作线程上的 sys.path(例如,在 MyWorker 构造函数中)不起作用的原因是 MyWorker类定义被腌制并运送给 worker 。然后,worker 会对其进行 unpickle,而 unpickle 类定义的过程需要导入 my_utils,而这会失败,因为 actor 构造函数还没有机会运行。

这里有几个可能的解决方案。

  1. 使用类似的内容运行脚本

    PYTHONPATH=$(dirname $(pwd)):$PYTHONPATH python main.py

    (来自working_dir/)。这应该可以解决问题,因为在这种情况下,工作进程是从调度程序进程派生的(当您调用 ray.init() 时,它是从主 Python 解释器派生的,因此环境变量将被继承由工作人员(sys.path 不会发生这种情况,大概是因为它不是环境变量)。

  2. 看起来像是添加了一行

    parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    os.environ["PYTHONPATH"] = parent_dir + ":" + os.environ.get("PYTHONPATH", "")

    main.py 中(在 ray.init() 调用之前)也可以出于与上述相同的原因工作。

  3. 考虑添加 setup.py 并将项目安装为 Python 包,以便它自动位于相关路径上。

关于python - 并行: Import a python file from sibling folder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54338013/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com