如何将弱引用更改为强引用?

How to change a weak reference to a strong reference?

我使用 RPyC 连接到客户端并使用参数对象调用服务公开方法。我想从暴露的方法中获取这个对象并用它做一些事情,但是这个对象是弱引用的,当时我想访问它的数据:我得到一个 ReferenceError 告诉我对象 "weakly-referenced object no longer exists"

如何从垃圾回收中保护弱引用对象?我怎样才能将其更改为强引用?

server.py(发送消息)

conn = rpyc.connect(ip,port)
bgsrv = rpyc.BgServingThread(conn)
conn.root.my_remote_method(a, b, c)  # a,b,c are integer, strings etc.
time.sleep(0.2)
bgsrv.stop()
conn.close()

client.py(处理数据并将其放入队列)

class MessageService(Service):
    def exposed_my_remote_method(self, a, b, c):
        ThreadedClient.queue.put([a,b,c])

other.py(读取队列)

def read_queue(self):
    """ Handle all the messages currently in the queue (if any) """
    while ThreadedClient.queue.qsize():
        try:
            msg = ThreadedClient.queue.get(0)
            self.read_message(msg)
        except Queue.Empty:
            pass

def read_message(self, msg):
    # do something with the data of a, b, c
    res = msg[0] + xy # ReferenceError

这不应该发生在基元(整数、字符串等)上,但肯定会发生在一般对象上。您需要在服务器中做的是 obtain 对象,它在服务器进程中创建它们的副本,不再依赖于要保留在客户端进程中的引用。

class MessageService(Service):
    def exposed_my_remote_method(self, a, b, c):
        a,b,c = rpyc.classic.obtain([a,b,c])
        ThreadedClient.queue.put([a,b,c])

这也可以通过在客户端进程中使用deliver来实现。

我用下面的套路解决了week references的问题(还有缺少属性的问题):

def rpyc_deep_copy(obj):
    """
    Makes a deep copy of netref objects that come as a result of RPyC remote method calls.
    When RPyC client obtains a result from the remote method call, this result may contain
    non-scalar types (List, Dict, ...) which are given as a wrapper class (a netref object). 
    This class does not have all the standard attributes (e.g. dict.tems() does not work) 
    and in addition the objects only exist while the connection is active. 
    To have a retuned value represented by python's native datatypes and to by able to use it 
    after the connection is terminated, this routine makes a recursive copy of the given object. 
    Currently, only `list` and `dist` types are supported for deep_copy, but other types may be added easily.
    Example:
        s = rpyc.connect(host1, port)
        result = rpyc_deep_copy(s.root.remote_method())
        # if result is a Dict:
        for k,v in result.items(): print(k,v)
    """
    if (isinstance(obj, list)):
        copied_list = []
        for value in obj: copied_list.append(rpyc_deep_copy(value))
        return copied_list
    elif (isinstance(obj, dict)):
        copied_dict = {}
        for key in obj: copied_dict[key] = rpyc_deep_copy(obj[key])
        return copied_dict
    else:
        return obj
    #end if
#end def