0

我有一个导入特定模块的 RpyC 服务器,应该公开这个模块内的一个类,以便可以从客户端继承这个类。

出于测试目的,我删除了模块导入/公开,并在我的 RPyC 服务中创建了一个名为暴露_TestClass 的简单类。

服务器端:rpyc_server.py

import rpyc
from rpyc.utils.server import ThreadedServer

class MyService(rpyc.Service):
    class exposed_TestClass:
        def exposed_Exec(self):
            print("original print of class")

t = ThreadedServer(MyService, port=12345)
t.start()

客户端:python3 shell

>>> import rpyc
>>> conn = rpyc.connect("localhost", 12345)
>>> conn.root.TestClass
<class 'exposed_TestClass'>
>>> conn.root.TestClass()
<exposed_TestClass object at 0x7f2dda642588>
>>> #calling the Exec function also works, prints at server side
>>> conn.root.TestClass().Exec()
>>>
>>>
>>> # test inheriting class
>>> class MyClass(conn.root.TestClass):
...     def NewMethod(self):
...         print("printing from new method")
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 220, in method
    return syncreq(_self, consts.HANDLE_CALLATTR, name, args, kwargs)
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 74, in syncreq
    conn = object.__getattribute__(proxy, "____conn__")
AttributeError: 'str' object has no attribute '____conn__'
4

1 回答 1

0

根据以下文档:https ://rpyc.readthedocs.io/en/latest/tutorial/tut2.html

瞧,netrefs(网络引用,也称为透明对象代理)是一种特殊的对象,它将在本地完成的所有事情委托给相应的远程对象。Netrefs 可能不是真正的函数或模块列表,但它们“尽最大努力”使外观和感觉与它们指向的对象相似……事实上,它们甚至欺骗了 python 的自省机制!

在客户端,如果你这样做:

import rpyc
conn = rpyc.connect("localhost", 12345)

o=conn.root.TestClass()
type_o = type(o)
print(type_o)

它会打印出来:

<netref class 'rpyc.core.netref.__main__.exposed_TestClass'>

因此,当尝试这样做时:

class MyClass(type_o):
    def NewMethod(self):
        print("printing from new method")

您从代理类定义继承而不是从远程类定义继承。所以当文档状态

他们“尽力而为”</p>

,我认为它排除了从远程类继承的可能性。如果有人能找到满足您要求的方法,我将非常高兴。

请注意,我通过使用以下行设置服务器进行了测试:

t = ThreadedServer(MyService, port=12345, protocol_config={ 'allow_all_attrs': True })
于 2020-11-20T04:54:42.180 回答