I Proxy
oggetti utilizzati da multiprocessing.BaseManager
e sue sottoclassi normalmente solo esporre metodi dagli oggetti che stanno riferimento a, non attributi. Ora, c'è multiprocessing.Manager().Namespace
, che fornisce una sottoclasse Proxy
fa fornire l'accesso agli attributi, piuttosto che ai metodi. Siamo in grado di creare la nostra Proxy
tipo che eredita da quella, che consente l'accesso a tutti i nostri attributi, così come l'accesso alla nostra funzione b
:
from multiprocessing.managers import BaseManager, NamespaceProxy
class TestClass(object):
def __init__(self, a):
self.a = a
def b(self):
print self.a
class MyManager(BaseManager): pass
class TestProxy(NamespaceProxy):
# We need to expose the same __dunder__ methods as NamespaceProxy,
# in addition to the b method.
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'b')
def b(self):
callmethod = object.__getattribute__(self, '_callmethod')
return callmethod('b')
MyManager.register('test', TestClass, TestProxy)
if __name__ == '__main__':
manager = MyManager()
manager.start()
t = TestClass(1)
print t.a
mt = manager.test(2)
print mt.a
mt.a = 5
mt.b()
uscita:
1
2
5
Edit:
Se si desidera essere in grado di aggiungere dinamicamente i metodi dalla classe originale a una classe Proxy, è possibile eseguire una delle seguenti operazioni:
from multiprocessing.managers import BaseManager, NamespaceProxy
import inspect
class TestClass(object):
def __init__(self, a):
self.a = a
def b(self):
print self.a
class AnotherClass(object):
def __init__(self, a):
self.a = a
def c(self):
print self.a
class MyManager(BaseManager): pass
class ProxyBase(NamespaceProxy):
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
class TestProxy(ProxyBase): pass
class AnotherProxy(ProxyBase): pass
def register_proxy(name, cls, proxy):
for attr in dir(cls):
if inspect.ismethod(getattr(cls, attr)) and not attr.startswith("__"):
proxy._exposed_ += (attr,)
setattr(proxy, attr,
lambda s: object.__getattribute__(s, '_callmethod')(attr))
MyManager.register(name, cls, proxy)
register_proxy('test', TestClass, TestProxy)
register_proxy('another', AnotherClass, AnotherProxy)
if __name__ == '__main__':
manager = MyManager()
manager.start()
mt = manager.test(2)
ma = manager.another(3)
mt.b()
ma.c()
mt.a = 5
ma.a = 6
mt.b()
ma.c()
grazie mille! –
Cosa succede se ho decine di metodi e una dozzina di attributi? Devo scriverli tutti nella classe TestProxy? O c'è una soluzione più generale? – selotec
@selotec Non ho tempo per fornire un'implementazione, ma dovresti essere in grado di eseguire iterate su tutti gli attributi della classe e aggiungere dinamicamente i metodi trovati alla tua classe Proxy e alla variabile '_exposed' – dano