通过键在多处理中访问值



使用多处理模块,我写了一台服务器来服务dict。现在,尝试通过客户端访问密钥,我会收到以下错误(server.pyclient.py位于帖子的底部(:

Traceback (most recent call last):
  File "client.py", line 19, in <module>
    item = my_dict[key]
TypeError: 'AutoProxy[get_dict]' object is not subscriptable

我相信这是由于我用SyncManager register() -ed的dict被腌制并以AutoProxy对象的方式传递的事实。当我使用print(dir(my_dict))检查Autoproxy对象的方法时,这就是我得到的:

['_Client', '__builtins__', '__class__', '__deepcopy__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_address_to_local', '_after_fork', '_authkey', '_callmethod', '_close', '_connect', '_decref', '_exposed_', '_getvalue', '_id', '_idset', '_incref', '_isauto', '_manager', '_mutex', '_serializer', '_tls', '_token', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

server.pyprint(dir(my_dict))的输出不同:

['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

看起来这个自动二粘体对象保留了dict对象的某些方法,但显然不是全部。至关重要的是,它不能保留__getitem__方法,这使我无法通过键访问项目。

如何通过密钥访问dict项目?同样,关于Proxy如何与Python多处理一起使用的任何解释都将非常有帮助。

注意:我不需要修改dict值,我只需要通过键提取它们。

server.py:

from multiprocessing.managers import SyncManager
my_dict = {'item_1': 1, 'item_2':2}
def get_my_dict():
    return my_dict
class MyManager(SyncManager):
    pass
if __name__ == "__main__":
    port_num = 4343
    MyManager.register("get_dict", get_my_dict)
    manager = MyManager(("127.0.0.1", port_num), authkey=b"password")
    manager.start()
    input("Press any key to kill server".center(50, "-"))
    manager.shutdown

client.py

from multiprocessing.managers import SyncManager
import sys
class MyManager(SyncManager):
    pass
MyManager.register("get_dict")
if __name__ == "__main__":
    port_num = 4343
    manager = MyManager(("127.0.0.1", port_num), authkey=b"password")
    manager.connect()
    my_dict = manager.get_dict()
    print("dict = %s" % (dir(my_dict)))
    keys = list(my_dict.keys())
    print(keys)
    for key in keys:
        print(my_dict[key])

您可以使用 get在任何一个版本中获取字典的元素。

Scott是正确的,您可以使用Get。否则,syncmanager.register采用一个参数exposed,该参数列出了通过代理曝光的orsect的方法。

您应该能够手动将__getitem__添加到暴露的列表中,例如:

exposed = [ x for x in dir (my_dict) if not x.startswith ('_') ]
exposed.append ('__getitem__')
MyManager.register ("get_dict", exposed = exposed)

正如Pydocs所说的:

  exposed is used to specify a sequence of method names which proxies
  for this typeid should be allowed to access using
  BaseProxy._callmethod(). (If exposed is None then proxytype._exposed_
  is used instead if it exists.) In the case where no exposed list is
  specified, all “public methods” of the shared object will be
  accessible. (Here a “public method” means any attribute which has a
  __call__() method and whose name does not begin with '_'.)

相关内容

  • 没有找到相关文章

最新更新