Superclass __init__ not recognizing its kwargs - python

I'm trying to use the StoppableThread class presented as an answer to another question:
import threading
# Technique for creating a thread that can be stopped safely
# Posted by Bluebird75 on StackOverflow
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(StoppableThread, self).__init__()
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
However, if I run something like:
st = StoppableThread(target=func)
I get:
TypeError: __init__() got an unexpected keyword argument 'target'
Probably an oversight on how this should be used.

The StoppableThread class does not take or pass any additional arguments to threading.Thread in the constructor. You need to do something like this instead:
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self,*args,**kwargs):
super(threading.Thread,self).__init__(*args,**kwargs)
self._stop = threading.Event()
This will pass both positional and keyword arguments to the base class.

You are overriding init and your init doesn't take any arguments. You should add a "target" argument and pass it through to your base class constructor with super or even better allow arbitrary arguments via *args and *kwargs.
I.e.
def __init__(self,*args,**kwargs):
super(threading.Thread,self).__init__(*args,**kwargs)
self._stop = threading.Event()

Related

Passing Generic type to inner class

In this code, I want to pass the type T to the inner class Emitter.
T = TypeVar('T')
class MySignal(Generic[T]):
class Emitter(QtCore.QObject,Generic[T]):
signal = Signal(T)
def __init__(self):
super(MySignal.Emitter, self).__init__()
def __init__(self):
self.emitter = MySignal.Emitter[T]()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
It doesn't behave as expected.
If I do
minMaxChanged=MySignal[tuple]()
Then minMaxChanged.emitter.__orig_class__.__args__[0] looks like T~ instead of tuple. The minMaxChanged class itself is as expected.
Generally, specifying Signal(typ) results in typ being the argument type expected to be passed to emit function. Consequently, in this case, Signal is called as if it were called without args, and calling emit with 1 argument fails since it expects no args.
I also expected the code
T = TypeVar('T')
class MySignal(Generic[T]):
class Emitter(QtCore.QObject):
signal = Signal(T)
def __init__(self):
super(MySignal.Emitter, self).__init__()
def __init__(self):
self.emitter = MySignal.Emitter()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
to work. However, the exact same issue remains.
Update
Notice that this is not a redundant complication. This class (partially brought here) is meant to wrap a Qt Signal which can only be omitted from class that is a Qt class. It meant to provide a generic signal wrapper. See how to emit signal from a non PyQt class?
Trying double inheritance MySignal(QtCore.QObject, Generic[T]) resulted in a c++ style crash.
#ekhumu suggestion indeed works. I hoped for something prettier.
class MySignal:
def __init__(self,typ):
Emitter = type('Emitter', (QtCore.QObject,), {'signal': Signal(typ)})
self.emitter = Emitter()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
def connect(self, slot):
self.emitter.signal.connect(slot)

Target a function with QThread

I'm aware of this structure
class MyThread(QThread):
def __init__(self):
super().__init__()
def run():
# do stuff
t = MyThread()
t.start()
With regular threading.Thread you can do something like this:
def stuff():
# do stuff
t = threading.Thread(target=stuff)
t.start()
Any way to do this in pyqt5 with QThreads? Something like this:
t = Qthread(target=stuff)
t.start()
I tried that but I got this error:
TypeError: 'target' is an unknown keyword argument
You can add the function to a custom argument in the __init__, create an instance attribute for its reference and then run it in the run.
class MyThread(QThread):
def __init__(self, target=None):
super().__init__()
self.target = target
def run():
if self.target:
self.target()
def stuff():
# do something
t = MyThread(target=stuff)
t.start()
Be aware that access to UI elements is not allowed in external threads, so don't use the threaded function to do anything related to UI: reading values and properties is unreliable, and writing can cause your program to crash.

Initialization of Multiple Inheritance in Python

I came across the following python code in which a class inherits from two parent classes. I am trying to understand the constructor of the class.
# wrapper.py:
#############
class EWrapper:
def __init__(self):
pass
...
# client.py
###########
class EClient(object):
def __init__(self, wrapper):
self.msg_queue = queue.Queue()
self.wrapper = wrapper
self.decoder = None
self.reset()
....
# Test.py
#########
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
Could someone kindly shed more light on EClient.__init__(self, self)? It's not clear to me the usage of two selfs. How does python know which self is which?
What is the process of constructing an object of TestApp?
In the call EClient.__init__(self, self) the first self becomes that of EClient in EClient's def __init__(self, wrapper):. Next, as you may see, the second self gets bound to wrapper in that call. TestApp inherits EWrapper so it uses itself as a wrapper for EClient.
When initializing TestApp you are using the self of the EWrapper and then EClient since that is the order defined in the class.

Python decorator to determine order of execution of methods

I have a basic class Framework with 3 methods that can be set by the user: initialize, handle_event and finalize.
These methods are executed by the method run:
class Framework(object):
def initialize(self):
pass
def handle_event(self, event):
pass
def finalize(self):
pass
def run(self):
self.initialize()
for event in range(10):
self.handle_event(event)
self.finalize()
I would like to create 3 decorators: on_initialize, on_event and on_finalize so that I could write such a class:
class MyFramework(Framework):
# The following methods will be executed once in this order
#on_initialize(precedence=-1)
def say_hi(self):
print('say_hi')
#on_initialize(precedence=0)
def initialize(self):
print('initialize')
#on_initialize(precedence=1)
def start_processing_events(self):
print('start_processing_events')
# The following methods will be executed in each event in this order
#on_event(precedence=-1)
def before_handle_event(self, event):
print('before_handle_event:', event)
#on_event(precedence=0)
def handle_event(self, event):
print('handle_event:', event)
#on_event(precedence=1)
def after_handle_event(self, event):
print('after_handle_event:', event)
# The following methods will be executed once at the end on this order
#on_finalize(precedence=-1)
def before_finalize(self):
print('before_finalize')
#on_finalize(precedence=0)
def finalize(self):
print('finalize')
#on_finalize(precedence=1)
def after_finalize(self):
print('after_finalize')
if __name__ == '__main__':
f = MyFramework()
f.run()
These decorators determine the order of execution of the optional methods the user may add to the class. I think that by default, initialize, handle_event and finalize should take precedence=0. Then the user could add any method with the right decorator and he will know when they get executed in the simulation run.
I have honestly no idea how to get started with this problem. Any help to push me in the right direction will be very welcome! Many thanks.
If you are using Python 3.6, this is a case that can take advantage of the new __init_subclass__ method. It is called on the superclass by subclasses when they are created.
Withut Python3.6 you have to resort to a metaclass.
The decorator itself can just mark each method with the needed data.
def on_initialize(precedence=0):
def marker(func):
func._initializer = precedence
return func
return marker
def on_event(precedence=0):
def marker(func):
func._event_handler = precedence
return func
return marker
def on_finalize(precedence=0):
def marker(func):
func._finalizer = precedence
return func
return marker
class Framework:
def __init_subclass__(cls, *args, **kw):
super().__init_subclass__(*args, **kw)
handlers = dict(_initializer=[], _event_handler=[], _finalizer=[])
for name, method in cls.__dict__.items():
for handler_type in handlers:
if hasattr(method, handler_type):
handlers[handler_type].append((getattr(method, handler_type), name))
for handler_type in handlers:
setattr(cls, handler_type,
[handler[1] for handler in sorted(handlers[handler_type])])
def initialize(self):
for method_name in self._initializer:
getattr(self, method_name)()
def handle_event(self, event):
for method_name in self._event_handler:
getattr(self, method_name)(event)
def finalize(self):
for method_name in self._finalizer:
getattr(self, method_name)()
def run(self):
self.initialize()
for event in range(10):
self.handle_event(event)
self.finalize()
If you will have a complex class hierarchy that should inherit the action methods properly, you wll have to merge the lists in the handlers dictionary with the ones in the superclass (get the superclass as cls.__mro__[1]) before applying then as class attributes.
Also, if you are using any Python < 3.6, you will need to move the logic on __init_subclass__ to a metaclass. Just put the code as it is on the __init__ method of a metaclass (and adjust the incoming parameters and super call as apropriate), and it should work just the same.
My idea is to use class based decorators, which are simple and gives intermediate context to share between decorated functions. So decorator would look like this (I am using python3.5):
class OnInitialize:
methods = {}
def __init__(self, precedence):
self.precedence = precedence
def __call__(self, func):
self.methods[self.precedence] = func
def wrapper(*a, **kw):
for precedence in sorted(self.methods.keys()):
self.methods[precedence](*a, **kw)
return wrapper
on decoration, first of all init is executed and it stores the precedence value for further use. Secondly the call is executed which just appends target function to the methods dictionary (Please note that call and methods structure could be customized to allow calling multiple methods with same precedence).
on the other hand, target class and methods would look like this
class Target:
#OnInitialize(precedence=-1)
def say_hi(self):
print("say_hi")
#OnInitialize(precedence=0)
def initialize(self):
print("initialize")
#OnInitialize(precedence=1)
def start_processing_events(self):
print("start_processing_events")
which ensures that, if one of the following methods are called, it will call all the decorated methods with given order.
target = Target()
target.initialize()
Hope it helps, please comment me below if you were interested in something other.

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