Python - call method in subclass - python

I am using a simpleWebSocket server class and have a 1 second interval timer that I would like to call methods in a couple of different classes.
the wsscb() class is the handler for the SimpleWebSocketServer(), how can I call a method from the wss() object from another object such as the udt() timer ?
Calling wss.wsscb().myfunc() results in an error: "AttributeError: 'SimpleWebSocketServer' object has no attribute 'wsscb'"
calling wsscb.myfunc() results in: TypeError: unbound method myfunc() must be called with wsscb instance as first argument (got nothing instead)
class wsscb(WebSocket):
def __init__(self, server, sock, address):
WebSocket.__init__(self, server, sock, address)
def myfunc(self):
self.send('some data')
def handleMessage(self):
pass
def handleConnected(self):
pass
class udt(Thread):
def __init__(self, event):
Thread.__init__(self)
self.stopped = event
def run(self):
while not self.stopped.wait(1.00):
wss.wsscb().myfunc()
xxx.yyy()().anotherfunc()
## Main
wss = SimpleWebSocketServer('', 4545,wsscb)
## Start Timer
stopFlag = Event()
self.udt = udt(stopFlag)
self.udt.start()
wss.serveforever()

There are a couple problems.
wss.wsscb() isn't valid. Typing that means you're trying to call a function in wss called wsscb(). wss is a SimpleWebSocketServer, and there is no function called wsscb(). A function is not the same as calling an object.
wsscb() won't work either, because in your class, you're saying it's takes a WebSocket object, which I assume takes some parameters, so you need to pass it those.
I think it would be best to make a subclass of SimpleWebSocketServer (instead of WebSocket), and put your custom function in there. Your comment says "wsscb() is a subclass of SimpleSocketServer", but it is not. It's a subclass of WebSocket.
You also never created an object of type wsscb.
If you can explain what you're specifically trying to achieve, and what myfunc() is, we may be able to help more
Also, you really shouldn't subclass Thread. Scrap the udt class you made and instead
def myfunc(wsscb_object):
while True:
time.sleep(1)
wsscb_object.myfunc()
#whatever else you want
wsscb_object = wsscb(#pass the parameters)
thread = Thread(target=myfunc, args=(some_socket))
thread.start()
You may also want to read up more on inheritance:
python subclasses
http://www.jesshamrick.com/2011/05/18/an-introduction-to-classes-and-inheritance-in-python/
Using inheritance in python

Related

Instance sharing across classes

I have this python script which has a listener class and a main class. A serial stream is created in the main class and a listener instance is created in the main class. The whole purpose of the listener is to send a message on the serial port when a listened property has changed. The problem is that the listener doesn't have access to the output stream created in the main class. The listener does an abrupt return when trying to execute the outputStream.write statement How can I give the listener access to the output stream?
import purejavacomm
import java.beansSensorListener
class MyListener(java.beans.PropertyChangeListener):
def propertyChange(self, event):
if (< some property has changed >) :
self.outputStream.write(message) # send notice on serial port
return
class MainClass(jmri.jmrit.automat.AbstractAutomaton) :
def __init__(self) :
self.portID = purejavacomm.CommPortIdentifier.getPortIdentifier("COM3")
self.port = self.portID.open("SerialCom", 50)
self.outputStream = self.port.getOutputStream()
return
def init(self) :
myListener = MyListener()
deviceList = devices.getNamedBeanSet()
for device in deviceList :
device.addPropertyChangeListener(myListener)
return
a = MainClass()
a.start();
It seems that really MyListener should either have a stream passed into the constructor or the callback (using lambda expression).
First, which is probably the cleanest way, would look like this:
def init(self) :
myListener = MyListener(self.outputStream)
Second version: device.addPropertyChangeListener(lambda x: myListener(x, self.outputStream)) Both need changes in the MyListener class to either constructor, or definition of propertyChange.
If you are set of sharing an instance of here are two options.
If you can modify arguments to MyListener constructor you pass in instance of MainClass to it:
def init(self) :
myListener = MyListener(self)
If not, a little bit more hacky way of doing this is by making MainClass a singelton (see example here), and then calling it's constructor within MyListener

__init__() got an unexpected keyword argument 'conne'

I have a problem with overriding the init method of the thread class.
I only need it to take a socket that i pass to the init method when I instantiate the thread object.
The code of the thread class is:
class client_handle(threading.Thread):
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def __init__(self, conne=None):
threading.Thread.__init__(self, conne=conne)
When i create a client_handle object i write:
socket_conn, addr = s.accept()
client_thread = client_handle(socket_conn)
I also searched in other posts but i couldn't solve my problem.
You need to assign conne manually as attribute of the instance. Passing it as argument to Thread.__init__ won't work (would be set as the group-argument of the Thread-class).
from threading import Thread
class ClientHandle(Thread):
def __init__(self, conne=None):
super().__init__() # Python 3
self.conne = conne
Thread.__init__ doesn't have a parameter named conne, so you have to pass the value as a positional argument instead.
def __init__(self, conne=None):
threading.Thread.__init__(self, conne)
Incidentally, the class attribute client_handle.conne doesn't seem to serve any purpose; you can probably get rid of it.
Update: passing a socket to Thread.__init__ in particular is clearly wrong, but this applies to any attempt to "invent" a parameter name like conne for a method that doesn't have a parameter named conne.

Why can't I override this method in python?

I'm trying to override a python class (first time doing this), and I can't seem to override this method. When I run this, my recv method doesn't run. It runs the superclasses's method instead. What am I doing wrong here? (This is python 2.7 by the way.)
import socket
class PersistentSocket(socket.socket):
def recv(self, count):
print("test")
return super(self.__class__, self).recv(count)
if __name__ == '__main__':
s = PersistentSocket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 2300))
print(s.recv(1)
The socket type (officially socket.SocketType, though socket.socket happens to be the same object) makes the strange choice of implementing recv and a few other methods as instance attributes, rather than as normal methods in the class dict. In socket.SocketType.__init__, it sets a self.recv instance attribute that overrides the recv method you tried to define.
Picking on the explanation from #user2357112, one thing that seems to have helped is to do a delattr(self, 'recv') on the class constructor (inheriting from socket.SocketType) and then define you own recv method; for example:
class PersistentSocket(socket.SocketType):
def __init__(self):
"""As usual."""
delattr(self, 'recv')
def recv(self, buffersize=1024, flags=0):
"""Your own implementation here."""
return None

Passing extra metadata to a RequestHandler using python's SocketServer and Children

I'm implementing a python application which is using ThreadingTCPServer and a custom subclass of BaseRequestHandler. The problem with this is that the ThreadingTCPServer seems to automatically spawn threads and create instances of the handler, calling their handle() function. However this leaves me with no way to pass data to the handler other than using global variables or class variables, both of which seem hackish. Is there any better way to do it?
Ideally this should be something like:
class ThreadedTCPServer(ThreadingTCPServer):
def process_request(self, *args, **kwargs):
ThreadingTCPServer.process_request(self, data, *args, **kwargs)
with the handler like
class ThreadedTCPRequestHandler(BaseRequestHandler):
def handle(self,data):
#do something with data
I stumbled upon the very same thing. My solution was the following:
class ThreadedTCPRequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
print(self.server.mycustomdata)
class ThreadedTCPServer(SocketServer.ThreadingTCPServer):
pass
server = ThreadedTCPServer((args.host, args.port), ThreadedTCPRequestHandler)
server.mycustomdata = 'foo.bar.z'
server.serve_forever()
The RequestHandler is called with a server object as a third parameter, and it is saved as self.server attribute, so you can access it. If you would set this attribute to a callable, you could easily call it, too:
def handle(self):
mycustomdata = self.server.mycustomdata()
The first answer worked for me, but I think it is cleaner to alter the __init__ method and pass the attribute in the constructor:
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
def __init__(self, host_port_tuple, streamhandler, Controllers):
super().__init__(host_port_tuple, streamhandler)
self.Controllers = Controllers
Note the third parameter 'Controllers' in the constructor, then the call to super without that parameter, then setting the new attribute Controllers to the property self.Controllers. The rest of the class is unchanged. Then, in your Requesthandler, you get access to the parameter using the 'server' attribute, as described above:
def handle(self):
self.Controllers = self.server.Controllers
<rest of your code>
It's much the same as the answer above but I find it a little cleaner because the constructor is overloaded and you simply add the attribute you want in the constructor:
server = ServerInterface.ThreadedTCPServer((HOST, PORT), ServerInterface.ThreadedTCPRequestHandler, Controllers)
Since handle is implemented by your BaseRequest subclass, it can get the data from itself without having it passed by the caller. (handle could also be a callable attribute of the request instance, such as a lambda—explicit user_data arguments are normally unnecessary in idiomatically designed python.)
Looking at the SocketServer code, it should be straightforward to override finish_request to pass the additional data to your BaseRequestHandler subtype constructor which would store it in the instance for handle to use.

What is causing "unbound method __init__() must be called with instance as first argument" from this Python code?

I have this class:
from threading import Thread
import time
class Timer(Thread):
def __init__(self, interval, function, *args, **kwargs):
Thread.__init__()
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.start()
def run(self):
time.sleep(self.interval)
return self.function(*self.args, **self.kwargs)
and am calling it with this script:
import timer
def hello():
print \"hello, world
t = timer.Timer(1.0, hello)
t.run()
and get this error and I can't figure out why: unbound method __init__() must be called with instance as first argument
You are doing:
Thread.__init__()
Use:
Thread.__init__(self)
Or, rather, use super()
This is a frequently asked question at SO, but the answer, in brief, is that the way you call your superclass's constructor is like:
super(Timer,self).__init__()
First, the reason you must use:
Thread.__init__(self)
instead of
Thread.__init__()
is because you are using the class name, and not an object (an instance of the class), so you cannot call a method in the same way as an object.
Second, if you are using Python 3, the recommended style for invoking a super class method from a sub class is:
super().method_name(parameters)
Although in Python 3 is possible to use:
SuperClassName.method_name(self, parameters)
It is an old style of syntax that is not the prefer style.
You just need to pass 'self' as an argument to 'Thread.init'. After that, it works on my machines.

Categories