Python 不序列化未在套接字中导入的对象
Python do not serialize object which is not imported in socket
我编写了以下简单的套接字应用程序,其中对象在单独的文件中定义并且可以正常工作。
# models_object.py
class Person(object):
def __init__(self,name,surname,age):
self.name = name
self.surname = surname
self.age = age
def __str__(self):
return self.name + " " + self.surname
#client.py
import cPickle,socket
from model_objects import Person
def client():
client = socket.socket()
host = socket.gethostname()
port = 8000
adem_kerenci = Person("Adem","Kerenci",22)
serialized_object = cPickle.dumps(adem_kerenci)
client.connect((host, port))
client.send(serialized_object)
client.close()
client()
#service.py
import cPickle,socket
def server():
server = socket.socket()
host = socket.gethostname()
port = 8000
server.bind((host, port))
server.listen(1)
connection, address = server.accept()
recieved_data = connection.recv(2**20)
print cPickle.loads(recieved_data)
connection.close()
server()
但是,如果我将 Person
class 定义写入 client.py
,代码会引发以下错误。
Traceback (most recent call last):
File "service.py", line 14, in <module>
server()
File "service.py", line 11, in server
print cPickle.loads(recieved_data)
AttributeError: 'module' object has no attribute 'Person'
导入和序列化有关系吗?
注意:我们尝试了 python 2.7
Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.
这意味着您在服务器中 unpickling 的对象也应该可以从具有相同 "fully qualified" name 的服务器代码导入,在第一个示例中是:model_objects.Person
。如果您尝试将 client.py
和 model_objects.py
拆分到一个文件夹中,将 service.py
拆分到另一个文件夹中,这在第一种情况下很明显,这会给您带来与尝试导入时相同的错误 model_objects.py
在 service.py
中,但找不到它。
所以在第二种情况下,您也可以将 class Person 复制到服务器代码,它会起作用,但这是不好的做法,或者为共享生产代码的客户端和服务器创建一个共享文件夹以及(更好的做法)。
这是因为在 unpickling 期间 python 需要对象的 class 来重新实例化对象并使用它。
我编写了以下简单的套接字应用程序,其中对象在单独的文件中定义并且可以正常工作。
# models_object.py
class Person(object):
def __init__(self,name,surname,age):
self.name = name
self.surname = surname
self.age = age
def __str__(self):
return self.name + " " + self.surname
#client.py
import cPickle,socket
from model_objects import Person
def client():
client = socket.socket()
host = socket.gethostname()
port = 8000
adem_kerenci = Person("Adem","Kerenci",22)
serialized_object = cPickle.dumps(adem_kerenci)
client.connect((host, port))
client.send(serialized_object)
client.close()
client()
#service.py
import cPickle,socket
def server():
server = socket.socket()
host = socket.gethostname()
port = 8000
server.bind((host, port))
server.listen(1)
connection, address = server.accept()
recieved_data = connection.recv(2**20)
print cPickle.loads(recieved_data)
connection.close()
server()
但是,如果我将 Person
class 定义写入 client.py
,代码会引发以下错误。
Traceback (most recent call last):
File "service.py", line 14, in <module>
server()
File "service.py", line 11, in server
print cPickle.loads(recieved_data)
AttributeError: 'module' object has no attribute 'Person'
导入和序列化有关系吗?
注意:我们尝试了 python 2.7
Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.
这意味着您在服务器中 unpickling 的对象也应该可以从具有相同 "fully qualified" name 的服务器代码导入,在第一个示例中是:model_objects.Person
。如果您尝试将 client.py
和 model_objects.py
拆分到一个文件夹中,将 service.py
拆分到另一个文件夹中,这在第一种情况下很明显,这会给您带来与尝试导入时相同的错误 model_objects.py
在 service.py
中,但找不到它。
所以在第二种情况下,您也可以将 class Person 复制到服务器代码,它会起作用,但这是不好的做法,或者为共享生产代码的客户端和服务器创建一个共享文件夹以及(更好的做法)。
这是因为在 unpickling 期间 python 需要对象的 class 来重新实例化对象并使用它。