Ste
Ste

Reputation: 13

Python: How to invoke a method from outside a class?

I have a really short and easy question:

How to invoke the send() method from another python file/class? I want to send a message from another component to client (connection is established).

I thought Ijust have to get the reference of the singleton instance and then just "send" like this:

server = Server(ip,port)
server.send("hello")

If I do it like that, I get the error:

NoneType' object has no attribute 'send'

Maybe "self" is here the problem...

here is the server class:

class Server(threading.Thread):

    ##############################################################################
    # Server: Singleton Instance
    ##############################################################################
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Server, cls).__new__(cls, *args, **kwargs)
        return cls._instance    

    ##############################################################################
    # Constructor of Server
    ##############################################################################
    def __init__(self, host, port):
        threading.Thread.__init__(self)
        print "[SERVER____] Creating Server Thread"
        self.host = host
        self.port = port
        self.__reset__()  

    ##############################################################################
    # Resetting local attributes
    ##############################################################################
    def __reset__(self):   
        print "[SERVER____] Reset"         
        self.serverSock = None
        self.clientSock = None
        self.clientAddr = None
        self.clientData = None
        self.isRunning = None
        self.isWaiting = None

    ###########################################################################                
    def send(self, message):
        print "[SERVER____] Sending Message", message
        self.clientSock.send(message)

    ##############################################################################
    # Stop the Server: Close the Socket and Reset
    ##############################################################################
    def stop(self):            
        # Close The Client Socket
        if(self.clientSock): 
            self.clientSock.close()
            print "[SERVER____] Aborting Client Socket"
        # Close The Server Socket    
        if(self.serverSock): 
            self.serverSock.close()
            print "[SERVER____] Aborting Server Socket"
        # Reset the Member Fields
        self.__reset__()
        print "[SERVER____] Aborting Server Thread"
        self._Thread__stop()

    ##############################################################################
    # Server.start()
    ##############################################################################
    def run(self):          
        try:
            # Create The Socket
            self.serverSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            print "[SERVER____] Creating Server Socket"
            # Set Socket Options
            #self.serverSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
            # Bind The New Socket
            self.serverSock.bind((self.host, self.port))
            print "[SERVER____] Binding Server Socket"
            print "[SERVER____] IP: ", self.host, " Port: ", self.port
            # Set The Awaiting Flag
            self.isWaiting = True;
            # Start The Server Loop
            while self.isWaiting:
                # Listen On New Socket
                self.serverSock.listen(1)
                print "[SERVER____] Listening Server Socket"
                # Accept New Connection            
                self.clientSock, self.clientAddr = self.serverSock.accept()     
                print "[SERVER____] Accepting New Connection: " , self.clientAddr
                # Set The Running Flag
                self.isRunning = True;     
                # Serve The Connection
                while self.isRunning:
                    print "[SERVER____] Want to recv message...."
                    try:
                        # Receive A New Data Block    
                        self.clientData = self.clientSock.recv(config.BUFFERSIZE)
                        # Process The New Data Block
                        if not self.clientData:                       
                            print "[SERVER____] Reset By Client Connection"
                            break
                        else:    
                            print "[SERVER____] Receiving Message: ", self.clientData
                            parser = MessageParser()
                            parser.parseSMMessage(self.clientData)                    
                    except socket.error:
                        print "[SERVER_ERR] Error at receiving data from client."                            
        except Exception as exc:
            print "[SERVER____] Server Thread Exception ", exc

Upvotes: 0

Views: 345

Answers (1)

interjay
interjay

Reputation: 110108

Your implementation of the singleton pattern is wrong, and this causes self.clientSock to be set to None before calling self.clientSock.send. The implementation is wrong because it will call __init__ each time you get the singleton instance. Basically, what happens is:

  1. You call Server(...) to get the instance.
  2. run is called on that instance. This sets self.clientSock.
  3. You call Server(...) to get the instance again. This will return the same instance due to your implementation of __new__, but __init__ will be called on it again and self.clientSock will be reset to None.
  4. Now the call to self.clientSock.send causes an exception.

I recommend avoiding using __new__ to implement a singleton if you need one (though not using a singleton at all is probably best). Some other methods are listed here.

Upvotes: 1

Related Questions