我是Pyro4的新手,需要深入了解它,还有什么比试用Pyro4包中的示例更好的方法?所以我的第一步是简单地完成一个工作,这就是“仓库”的例子。这个想法是让一个人访问仓库并选择要采取或存储的物品。 文件“warehouse.py”包含Pyro deamon信息,而“visit.py”则包含人员和仓库之间的交互。
名称服务器(在我的情况下:Hodor,由pyro4-ns -n Hodor
启动并在C:\Windows\System32\drivers\etc
中的主机文件中有一个条目)和“warehouse.py”必须在两个单独的终端窗口中运行。每次我通过第三个终端窗口中的“visit.py”开始通信时,首先它会工作并询问我是否要存储某些内容。如果我这样做,我会收到错误消息:
“Pyro4.errors.SerializeError:不支持的序列化类:person.Visitor”
File "visit.py", line 10, in <module>
janet.visit(warehouse)
File "C:\Users\RickJames\Pyro_other_machine\person.py", line 14, in visit
self.retrieve(warehouse)
File "C:\Users\RickJames\Pyro_other_machine\person.py", line 25, in retrieve
warehouse.take(self, item)
File "C:\Python34\lib\site-packages\Pyro4\core.py", line 171, in __call__
return self.__send(self.__name, args, kwargs)
File "C:\Python34\lib\site-packages\Pyro4\core.py", line 428, in _pyroInvoke
raise data
Pyro4.errors.SerializeError: unsupported serialized class: person.Visitor
这是“warehouse.py”:
from __future__ import print_function
import Pyro4
import person
class Warehouse(object):
def __init__(self):
self.contents=["chair","bike","flashlight","laptop","couch"]
def list_contents(self):
return self.contents
def take(self, person, item):
self.contents.remove(item)
print("{0} took the {1}.".format(person.name, item))
def store(self, person, item):
self.contents.append(item)
print("{0} stored the {1}.".format(person.name, item))
def main():
warehouse=Warehouse()
Pyro4.Daemon.serveSimple(
{
warehouse: "warehouse"
},
host = "Hodor",
ns=True)
if __name__=="__main__":
main()
“person.py”:
from __future__ import print_function
import sys
if sys.version_info<(3,0):
input=raw_input
class Visitor(object):
def __init__(self, name):
self.name=name
def visit(self, warehouse):
print("This is {0}.".format(self.name))
self.deposit(warehouse)
self.retrieve(warehouse)
print("Thank you, come again!")
def deposit(self, warehouse):
print("The warehouse contains:", warehouse.list_contents())
item=input("Type a thing you want to store (or empty): ").strip()
if item:
warehouse.store(self, item)
def retrieve(self, warehouse):
print("The warehouse contains:", warehouse.list_contents())
item=input("Type something you want to take (or empty): ").strip()
if item:
warehouse.take(self, item)
最后是“visit.py”:
import sys
import Pyro4
import Pyro4.util
from person import Visitor
warehouse=Pyro4.Proxy("PYRONAME:warehouse")
janet=Visitor("Janet")
henry=Visitor("Henry")
janet.visit(warehouse)
henry.visit(warehouse)
我知道默认情况下Pyro4使用序列化程序“serpent”。我试图切换到'marshal','json','dill'和'pickle',但没有一个能解决我的问题。此外,由于我阅读了一些序列化程序的所有安全问题,我想保留“蛇”。
答案 0 :(得分:0)
您的源文件错误。你自己打字了吗?你是从哪里得到的?因为你在这里展示的那些是这些示例文件的旧版本(3年前!)这些旧版本确实不再使用最新版本的Pyro4,因为自从之后对序列化器机制进行了一些更改然后
您的代码不再起作用的最重要原因是因为您的访问者&#39;访客&#39; class,在存放和检索方法中,代码将Visitor实例传递给Warehouse pyro服务。除非你告诉Pyro如何序列化它,否则这是不可能的。由于这只是一个简单的例子,这里不包括这种复杂性,但你可以在Pyro的文档中阅读它。该示例的正确版本仅将人员的名称传递给仓库服务,从而完全避免了该问题。
可以从the current Pyro4 documentation复制正确的版本,或者在Pyro4源代码发布的examples/warehouse/phase3文件夹中为您提供。
为完整起见,正确的版本如下。 &#34; person.py&#34;:
from __future__ import print_function
import sys
if sys.version_info < (3, 0):
input = raw_input
class Person(object):
def __init__(self, name):
self.name = name
def visit(self, warehouse):
print("This is {0}.".format(self.name))
self.deposit(warehouse)
self.retrieve(warehouse)
print("Thank you, come again!")
def deposit(self, warehouse):
print("The warehouse contains:", warehouse.list_contents())
item = input("Type a thing you want to store (or empty): ").strip()
if item:
warehouse.store(self.name, item)
def retrieve(self, warehouse):
print("The warehouse contains:", warehouse.list_contents())
item = input("Type something you want to take (or empty): ").strip()
if item:
warehouse.take(self.name, item)
然后,&#34; visit.py&#34;:
# This is the code that visits the warehouse.
import sys
import Pyro4
import Pyro4.util
from person import Person
sys.excepthook = Pyro4.util.excepthook
warehouse = Pyro4.Proxy("PYRONAME:example.warehouse")
janet = Person("Janet")
henry = Person("Henry")
janet.visit(warehouse)
henry.visit(warehouse)
最后,&#34; warehouse.py&#34;:
from __future__ import print_function
import Pyro4
@Pyro4.expose
class Warehouse(object):
def __init__(self):
self.contents = ["chair", "bike", "flashlight", "laptop", "couch"]
def list_contents(self):
return self.contents
def take(self, name, item):
self.contents.remove(item)
print("{0} took the {1}.".format(name, item))
def store(self, name, item):
self.contents.append(item)
print("{0} stored the {1}.".format(name, item))
def main():
Pyro4.Daemon.serveSimple(
{
Warehouse: "example.warehouse"
},
ns=True)
if __name__ == "__main__":
main()
这些与Pyro 4.45配合使用。