在 Jupyter 笔记本中,从使用字符串引用的类创建一个对象以与 ray 一起使用

问题描述 投票:0回答:1

我的 3.6.3 Jupyterlab 笔记本正在运行 Python 3.10.11。我正在尝试使用 Ray 来实现一些非对称代码。这很简单,除了在我的远程函数中我尝试使用包含类名的字符串来实现类对象。

我们有许多触发器,每个触发器都会导致使用特定的类。我们不能执行一堆 if 语句来创建类对象,因为触发器可能会改变。

以下代码是我正在尝试执行的示例。 “job1”之所以有效,是因为我直接实例化了类对象。 “job2”不起作用,因为我使用 eval() 来实例化类对象。

import ray
ray.init(ignore_reinit_error=True)

# Usually imported with a %run class_notebook.ipynb command.
class Test:
    def nothing(self):
        return True
        
@ray.remote
def do_it1():
    x = Test()   # Class object created directly. This works.
    return x.nothing()

@ray.remote
def do_it2():
    x = eval("Test")()   # Class object created using a string. This causes issues later.
    return x.nothing()    
    
job1 = do_it1.remote()

job2 = do_it2.remote()

ray.get(job1)

ray.get(job2)   # Error occurs here

错误信息是:

---------------------------------------------------------------------------
RayTaskError(NameError)                   Traceback (most recent call last)
Cell In[9], line 1
----> 1 ray.get(job2)

File /opt/conda/lib/python3.10/site-packages/ray/_private/auto_init_hook.py:24, in wrap_auto_init.<locals>.auto_init_wrapper(*args, **kwargs)
     21 @wraps(fn)
     22 def auto_init_wrapper(*args, **kwargs):
     23     auto_init_ray()
---> 24     return fn(*args, **kwargs)

File /opt/conda/lib/python3.10/site-packages/ray/_private/client_mode_hook.py:103, in client_mode_hook.<locals>.wrapper(*args, **kwargs)
    101     if func.__name__ != "init" or is_client_mode_enabled_by_default:
    102         return getattr(ray, func.__name__)(*args, **kwargs)
--> 103 return func(*args, **kwargs)

File /opt/conda/lib/python3.10/site-packages/ray/_private/worker.py:2493, in get(object_refs, timeout)
   2491     worker.core_worker.dump_object_store_memory_usage()
   2492 if isinstance(value, RayTaskError):
-> 2493     raise value.as_instanceof_cause()
   2494 else:
   2495     raise value

RayTaskError(NameError): ray::do_it2() (pid=25675, ip=172.31.3.78)
  File "/tmp/ipykernel_25494/1701015360.py", line 3, in do_it2
  File "<string>", line 1, in <module>
NameError: name 'Test' is not defined

我需要在 do_it2 函数中做什么来使用字符串创建类对象的实例?

[编辑]为了实例化我的类对象,我尝试使用 globals() 但这也不起作用。

x = globals()['Test']()

[/编辑]

python asynchronous jupyter-notebook ray
1个回答
0
投票

我最终在函数外部创建了类对象,然后将其作为参数传递。

所以,相关的变化看起来像这样......

@ray.remote
def doit2(my_object):
   return my_object.nothing()

job2 = do_it2.remote(eval("Test")())
© www.soinside.com 2019 - 2024. All rights reserved.