1

我已经编写了以下简单的套接字应用程序,其中在单独的文件中定义了对象并且它可以工作。

# 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类定义写入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

4

1 回答 1

1

文档

请注意,函数(内置的和用户定义的)是通过“完全限定”名称引用而不是值来腌制的。这意味着只有函数名和定义函数的模块的名称被腌制。函数的代码和它的任何函数属性都没有被腌制。因此,定义模块必须在 unpickling 环境中是可导入的,并且模块必须包含命名对象,否则将引发异常。

这意味着您在服务器中取消腌制的对象也应该可以从具有相同“完全限定”名称的服务器代码导入,在第一个示例中是:model_objects.Person. 如果您尝试将client.pyand拆分到model_objects.py一个文件夹和service.py另一个文件夹中,这在第一种情况下很明显,这会给您带来与尝试在其中导入但找不到它相同的model_objects.py错误service.py

因此,在第二种情况下,您也可以将 Person 类复制到服务器代码中,它会起作用,但这是不好的做法,或者为客户端和服务器创建一个共享文件夹,这也是共享的生产代码(更好的做法)。

这是因为在 unpickling 期间,python 需要对象的类来重新实例化对象并使用它。

于 2016-10-20T12:52:30.003 回答