I have a question that sounds perhaps strange, but I want to call a function of my parent class inside my children.
I use tkinter and MyChild allready inherrit from a frame.
ex:
class MyParent:
def __init__(self):
do_things()
def myfunction(self):
child_class = MyChild()
def call_me(self):
print("I'm here!")
class MyChild:
def __init__(self):
do_things()
def my_call(self):
#here call the call_me function
here I want that when in MyChild class the my_call function is called, it calls the call_me function of the MyParent class.
I just want to know if and how it is possible to call call_me in the my_call function like Myparent.call_me()
Based on the code in your question, your child will have to be told what its parent is. This is normally done when you create the child. The child can keep a reference, so that it can be used whenever it needs to call a method on the parent.
Example:
class MyParent:
def myfunction(self):
child_class = MyChild(parent=self)
def call_me(self):
print("I'm here!")
class MyChild:
def __init__(self, parent):
self.parent = parent
do_things()
def my_call(self):
self.parent.call_me()
Related
In Python, is there a way to call a commonly named method for all instances of a class, including inheritance-related class instances? Using the example below, when c.process() is called, I would like all "process" methods for all Parent-related instances to trigger. As such, I would want the output to print "Parent process" and "ChildType1 process" for instance c, "Parent process" and "ChildType1 process" for instance d, and "Parent process" and "ChildType2 process" for instance e -- all simply by making one call (perhaps "c.process()", for example). Or this there another architecture to achieve similar means--perhaps using arrays of class instances? Thanks!
class Parent:
def __init__(self):
pass
def process(self):
print("Parent process")
class ChildType1(Parent):
def __init__(self):
super().__init__()
def process(self):
print("ChildType1 process")
class ChildType2(Parent):
def __init__(self):
super().__init__()
def process(self):
print("ChildType2 process")
c = ChildType1()
d = ChildType1()
e = ChildType2()
c.process()
If the child method should always call the parent method, the solution should be simply using super, similarly to what you already did in __init__.
def process(self):
super().process()
print("ChildType1 process")
If for some reason you want to do this without changing the implementation of process, you could iterate over the superclasses of the object and invoke the process method wherever it is defined. This is a quick untested stub of a solution:
for cls in type(c).mro():
if hasattr(cls, "process"):
cls.process(c)
I'm writing a feature generation class that can be extendable. For example in the following example any method that starts with generate is a feature generation method:
class FeatureGenerator:
def __init__(self):
self.generate_a()
self.generate_b()
def method_a(self): pass
def generate_a(self): do stuffs
def generate_b(self): do stuffs
I want to execute all methods with generate prefix within init. However, I don't want to add it manually every time I write a new method. One solution could be writing a decorator that will add it to a list and then execute all elements in the list within init. But I am not sure that's a good idea. Is there any pythonic way to do that?
Using the dir of the instance:
class FeatureGenerator:
def __init__(self):
for name in dir(self):
attr = getattr(self, name)
if callable(attr) and name.startswith("generate"):
attr()
def method_a(self): pass
def generate_a(self): print("gen a")
def generate_b(self): print("gen b")
I am trying to exectute the below code but I get errors.
class base:
def callme(data):
print(data)
class A(base):
def callstream(self):
B.stream(self)
def callme(data):
print("child ", data)
class B:
def stream(data):
# below statement doesn't work but I want this to run to achieve run time
# polymorphism where method call is not hardcoded to a certain class reference.
(base)data.callme("streaming data")
# below statement works but it won't call child class overridden method. I
# can use A.callme() to call child class method but then it has to be
# hardcoded to A. which kills the purpose. Any class A or B or XYZ which
# inherits base call should be able to read stream data from stream class.
# How to achive this in Python? SO any class should read the stream data as
# long as it inherits from the base class. This will give my stream class a
# generic ability to be used by any client class as long as they inherit
# base class.
#base.callme("streaming data")
def main():
ob = A()
ob.callstream()
if __name__=="__main__":
main()
I got the output you say you're looking for (in a comment rather than the question -- tsk, tsk) with the following code, based on the code in your question:
class base:
def callme(self, data):
print(data)
class A(base):
def callstream(self):
B.stream(self)
def callme(self, data):
print("child", data)
class B:
#classmethod
def stream(cls, data):
data.callme("streaming data")
def main():
ob = A()
ob.callstream()
if __name__=="__main__":
main()
Basically, I just made sure the instance methods had self parameters, and since you seem to be using B.stream() as a class method, I declared it as such.
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.
I have the following code:
class Functions(QObject):
mysig = Signal(filename)
def __init__(self, parent=None):
super(Functions, self).__init__(parent)
self.result = None
def showDialog(self, filename):
self.mysig.emit(filename)
def grabResult(self):
while not self.result:
time.sleep(5)
return result #this is the question
def setResult(self, result):
self.result = result
The other part of the code has this:
class Dialog(QDialog):
anotherSig = Signal(str)
fun = Functions()
def __init__(self, parent=None, filename=filename):
self.filename = filename
#Here it displays a picture based on the filename parameter
def okButtonClicked(self):
text = self.lineedit.text()
fun.setResult(text)
#Tried also this:
self.anotherSig.emit(text)
The Functions() class is called from a worker QThread (not shown here).
I guess my question is this: how do I tell my Functions class that the user has entered the the text and clicked the OK button? I tried connecting that anotherSig Signal, but when I try to do so, Qt complains about QPixmaps not being safe to be set from a different thread, and it doesn't work.
The method that I am using here "works", but I feel it's not very reliable. Plus, it only works when all of the relevant methods in the Functions class are #classmethod - this way, for some reason, it doesn't work. The setResult is called (I added a print statement to make sure), but the grabResult still shows self.result as None.
This code is not working because the call to showDialog is happening on the instantiation of a Functions object that is an attribute of what ever object is off on the other thread. Your fun in Dialog, which you set the result on, is a different instantiation.
To move the results back to the original Functions object I think you need to connect anotherSig of the Dialog object to the setResult function on the Functions object you want to get the results back.
Does something like this work (hard to test this with out a good bit of boiler plate).
class Functions(QObject):
mysig = Signal(filename,Functions)
def __init__(self, parent=None):
super(Functions, self).__init__(parent)
self.result = None
def showDialog(self, filename):
self.mysig.emit(filename,self)
def grabResult(self):
while not self.result:
time.sleep(5)
return result #this is the question
#QtCore.Slot(str)
def setResult(self, result):
self.result = result
def connection_fun(filename,fun):
d = Dialog(filename)
# what ever else you do in here
d.anotherSig.connect(fun.setResult))
Using time.sleep causes your application to freeze. One method for making your class wait is using QEventLoop like this:
loop = QEventLoop()
myDialog.mySignal.connect(loop.quit)
loop.exec_()