1

I have written following simple socket application in which object defined in separate file and it works.

# 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()          

However, if I write Person class definition into client.py, code raises following error.

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'

Is there any relation between importing and serializing?

Note: We tried python 2.7

1 Answers1

1

From documentation:

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.

This means that the object you are unpickling in the server should be importable too from the server code with the same "fully qualified" name which in the first example is: model_objects.Person. This is apparent in the first case if you try splitting the client.py and model_objects.py in one folder and service.py in another folder which will give you the same error as it is trying to import model_objects.py inside service.py but it couldn't find it.

So in the second case you can copy the class Person as well to the server code and it will work but this is bad practice or make a shared folder for both client and server which is shared production code as well (better practice).

This is because during unpickling python needs the class of the object to reinstantiate the object and use it.

Community
  • 1
  • 1
sharno
  • 630
  • 8
  • 14