为什么在尝试使用 SharedMemoryManager (python 3.8) 替代 BaseManager 时会出现 NameError?
Why do we get a NameError when trying to use the SharedMemoryManager (python 3.8) as a replacement for the BaseManager?
Python 3.8 引入了新的共享内存功能。我们正在尝试使用 SharedMemoryManager
并抛出 NameError
。
我认为我们在复杂的场景中可能会做错什么,所以我使用 python 文档片段对其进行了分解。
try:
# python >= 3.8
from multiprocessing.managers import SharedMemoryManager as Manager
except:
# python < 3.8
from multiprocessing.managers import BaseManager as Manager
class MathsClass:
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y
class MyManager(Manager):
pass
MyManager.register('Maths', MathsClass)
if __name__ == '__main__':
with MyManager() as manager:
maths = manager.Maths()
print(maths.add(4, 3)) # prints 7
print(maths.mul(7, 8)) # prints 56
这几乎取自多处理文档(后备导入除外)并且在 python 3.7 中工作正常但在 python 3.8 中抛出以下错误:
Traceback (most recent call last):
File "scripts/debug_shared_memory_issue.py", line 21, in <module>
maths = manager.Maths()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 740, in temp
token, exp = self._create(typeid, *args, **kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 625, in _create
id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 91, in dispatch
raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError:
---------------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 210, in handle_request
result = func(c, *args, **kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 1312, in create
if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
NameError: name 'self' is not defined
---------------------------------------------------------------------------
python 3.8 的发行说明和文档说 SharedMemoryManager
是 "A subclass of BaseManager",因此我们希望它可以作为直接替代品。但似乎并非如此。我们做错了什么?查看当前 CPython 的 3.8 分支,似乎没有对此进行相关更改。在 Python 3.9 中,create
函数中有一个明确的 self
arg。但是 3.9 是 WIP,所以我们宁愿不在生产软件中使用它。
感谢您的帮助!
这是 python/cpython@142566c (v3.9.0a1) 中修复的错误。
您可以从 python/cpython/blob/v3.9.0a1/Lib/multiprocessing/managers.py#L1269-L1277:
打补丁
from multiprocessing.managers import SharedMemoryManager as Manager
import sys
if sys.version_info < (3, 9):
from multiprocessing.managers import Server, SharedMemoryServer
def create(self, c, typeid, /, *args, **kwargs):
if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
kwargs['shared_memory_context'] = self.shared_memory_context
return Server.create(self, c, typeid, *args, **kwargs)
SharedMemoryServer.create = create
Python 3.8 引入了新的共享内存功能。我们正在尝试使用 SharedMemoryManager
并抛出 NameError
。
我认为我们在复杂的场景中可能会做错什么,所以我使用 python 文档片段对其进行了分解。
try:
# python >= 3.8
from multiprocessing.managers import SharedMemoryManager as Manager
except:
# python < 3.8
from multiprocessing.managers import BaseManager as Manager
class MathsClass:
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y
class MyManager(Manager):
pass
MyManager.register('Maths', MathsClass)
if __name__ == '__main__':
with MyManager() as manager:
maths = manager.Maths()
print(maths.add(4, 3)) # prints 7
print(maths.mul(7, 8)) # prints 56
这几乎取自多处理文档(后备导入除外)并且在 python 3.7 中工作正常但在 python 3.8 中抛出以下错误:
Traceback (most recent call last):
File "scripts/debug_shared_memory_issue.py", line 21, in <module>
maths = manager.Maths()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 740, in temp
token, exp = self._create(typeid, *args, **kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 625, in _create
id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 91, in dispatch
raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError:
---------------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/managers.py", line 210, in handle_request
result = func(c, *args, **kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 1312, in create
if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
NameError: name 'self' is not defined
---------------------------------------------------------------------------
python 3.8 的发行说明和文档说 SharedMemoryManager
是 "A subclass of BaseManager",因此我们希望它可以作为直接替代品。但似乎并非如此。我们做错了什么?查看当前 CPython 的 3.8 分支,似乎没有对此进行相关更改。在 Python 3.9 中,create
函数中有一个明确的 self
arg。但是 3.9 是 WIP,所以我们宁愿不在生产软件中使用它。
感谢您的帮助!
这是 python/cpython@142566c (v3.9.0a1) 中修复的错误。
您可以从 python/cpython/blob/v3.9.0a1/Lib/multiprocessing/managers.py#L1269-L1277:
打补丁from multiprocessing.managers import SharedMemoryManager as Manager
import sys
if sys.version_info < (3, 9):
from multiprocessing.managers import Server, SharedMemoryServer
def create(self, c, typeid, /, *args, **kwargs):
if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"):
kwargs['shared_memory_context'] = self.shared_memory_context
return Server.create(self, c, typeid, *args, **kwargs)
SharedMemoryServer.create = create