如何解决如何在RPyC中访问嵌套数据的公共属性?
我正在尝试通过遵循此document来访问RPyC调用上的公共属性,但是看不到它如文档中所述那样起作用。
文档说,如果您未指定protocol_config={'allow_public_attrs': True,}
,则即使是内置数据类型的公共属性也将无法访问。但是,即使我们指定了此设置,也无法访问嵌套数据结构的公共属性?
RPyC服务器代码。
import pickle
import rpyc
class MyService(rpyc.Service):
def on_connect(self,conn):
# code that runs when a connection is created
# (to init the service,if needed)
pass
def on_disconnect(self,conn):
# code that runs after the connection has already closed
# (to finalize the service,if needed)
pass
def exposed_get_answer(self): # this is an exposed method
return 42
exposed_the_real_answer_though = 43 # an exposed attribute
def get_question(self): # while this method is not exposed
return "what is the airspeed veLocity of an unladen swallow?"
def exposed_hello(self,collection):
print ("Collection is ",collection)
print ("Collection type is ",type(collection).__name__)
for item in collection:
print ("Item type is ",type(item).__name__)
print(item)
def exposed_hello2(self,collection):
for item in collection:
for key,val in item.items():
print (key,val)
def exposed_hello_json(self,collection):
for item in collection:
item = json.loads(item)
for key,val)
if __name__ == "__main__":
from rpyc.utils.server import ThreadedServer
t = ThreadedServer(
MyService(),port=3655,protocol_config={'allow_public_attrs': True,}
)
t.start()
客户端呼叫
>>> import rpyc
>>> rpyc.__version__
(4,2)
>>> c = rpyc.connect('a.b.c.d',3655) ; client=c.root
#案例1 如果数据为嵌套结构(使用内置数据类型),则无法使用。
>>> data
[{'a': [1,2],'b': 'asa'}]
>>> client.hello2(data)
...
AttributeError: cannot access 'items'
========= Remote Traceback (2) =========
Traceback (most recent call last):
File "/root/lydian.egg/rpyc/core/protocol.py",line 329,in _dispatch_request
res = self._HANDLERS[handler](self,*args)
File "/root/lydian.egg/rpyc/core/protocol.py",line 590,in _handle_call
return obj(*args,**dict(kwargs))
File "sample.py",line 33,in exposed_hello2
for key,val in item.items():
File "/root/lydian.egg/rpyc/core/netref.py",line 159,in __getattr__
return syncreq(self,consts.HANDLE_GETATTR,name)
File "/root/lydian.egg/rpyc/core/netref.py",line 75,in syncreq
return conn.sync_request(handler,proxy,line 471,in sync_request
return self.async_request(handler,*args,timeout=timeout).value
File "/root/lydian.egg/rpyc/core/async_.py",line 97,in value
raise self._obj
_get_exception_class.<locals>.Derived: cannot access 'items'
案例2:解决方法,使用json(可怜的咸菜)将嵌套数据作为字符串传递,并在服务器端进行解码。
>>> jdata = [json.dumps({'a': [1,'b':"asa"})].
>>> client.hello_json(jdata) # Prints following at remote endpoint.
a [1,2]
b asa
案例3: 有趣的是,在第一级,内置项可以访问,例如 你好方法。但是,对嵌套数据进行调用会产生错误。
>>> client.hello([1,2,3,4]) # Prints following at remote endpoint.
Collection is [1,4]
Collection type is list
Item type is int
1
Item type is int
2
Item type is int
3
Item type is int
4
我有解决问题的方法/解决方案(上述情况2),但正在寻找有关为何不允许这样做或是否有错误的解释。感谢您的投入。
解决方法
该问题与嵌套数据无关。
您的问题是您不允许在客户端使用公共属性。 解决方法很简单:
c = rpyc.connect('a.b.c.d',3655,config={'allow_public_attrs': True})
请记住,rpyc 是一种对称协议(请参阅 https://rpyc.readthedocs.io/en/latest/docs/services.html#decoupled-services)。
在您的情况下,服务器尝试访问客户端的对象,因此必须在客户端设置 allow_public_attrs。 实际上,对于您的具体示例,无需在服务器端设置 allow_public_attrs。
关于案例 3:
在 for item in collection:
行中,服务器尝试访问两个字段:collection.__iter__
和 collection.__next__
。
默认情况下,这两个字段都被视为“安全属性”,这就是您没有在那里出错的原因。
检查 rpyc 中的默认配置字典:
>>> import rpyc
>>> rpyc.core.protocol.DEFAULT_CONFIG
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。