Complete brain fart here and not even sure I am asking the right question. How do I add/change a method of a class that exists within a class?
I am building a QT GUI designed in QtDesigner. My Python program imports and makes a new class subclassed to the GUI file class. I want to change a method to a button within that class.
So basically I have the below, and I want to add a method to 'aButton'.
qtDesignerFile.py
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.aButton = QtGui.QPushButton()
myPythonFile.py
import qtDesignerFile
class slidingAppView(QMainWindow,slidingGuiUi.Ui_MainWindow):
def __init__(self,parent=None):
super(slidingAppView,self).__init__(parent)
To add to Joran's answer, methods added like this:
def foo():
pass
instance.foo = foo
will act like static methods (they won't have the instance passed as first argument). If you want to add a bound method, you can do the following:
from types import MethodType
def foo(instance):
# this function will receive the instance as first argument
# similar to a bound method
pass
instance.foo = MethodType(foo, instance, instance.__class__)
self.aButton.PrintHello = lambda : print "hello!"
or
def aMethod():
do_something()
self.aButton.DoSomething = aMethod
either should work... probably more ways also ... this assumes aButton is a python class that inherits from Object
Related
What is the difference between creating two class one inheriting other and passing first class instance to another class init method ?
Like below,
method 1:
class ht(object):
def __init__(self):
pass
def ch(self):
self.filename="hellgmhjkl"
class tt():
def __init__(self,ob1,ob3):
self.ob1=ob1
self.ob3=ob3
self.b=5
def display(self):
print(ob1.filename)
print(self.ob3.d)
class kk():
def __init__(self):
self.c=3
def hel(self):
self.d=self.c+5
if __name__ == '__main__':
ob1=ht()
ob1.ch()
ob3=kk()
ob3.hel()
ob2=tt(ob1,ob3)
ob2.display()
method 2:
class ht(object):
def __init__(self):
pass
def ch(self):
self.filename="hellgmhjkl"
class tt(ht):
def __init__(self,ob1,ob3):
self.ob1=ob1
self.ob3=ob3
self.b=5
def display(self):
print(ob1.filename)
print(self.ob3.d)
class kk():
def __init__(self):
self.c=3
def hel(self):
self.d=self.c+5
if __name__ == '__main__':
ob1=ht()
ob1.ch()
ob3=kk()
ob3.hel()
ob2=tt(ob1,ob3)
ob2.display()
What is the diff between method 1 and 2 ?
My requirement is I have several classes : config.py, log.py, analyse.py, HTTPrequest.py, request.py, attack.py
All above classes needs the class variables values from config.py and log.py.
And, analyse.py needs values from request.py and HTTPRequest,py and attack.y needs values from request.py.
Can anybody help me how to inherit like multiple or multilevel or usecomposition or just pass class objects and how?
You inherit from classes when you want to modify behavior of an existing object; as inheritance will give you all the existing properties, methods and behaviors of the parent object; and all you have to do is code your own customization. Your new object is a derivative of the parent object.
Passing a class means to intend to use the object of that class as is, perhaps instantiate a new instance of it.
Remember that classes are just factories for creating custom objects (or types).
If you just need values from a specific file, simply import them:
from request import a, b, c
from HTTPRequest import one, two, three
its working but methods are executed twice always:
init.py
HTTPreq.py
anal.py
tree_structure
I am quite new to python, so pardon me for basic question. I tried google for past few days but could not make it in my program.
Can anyone show me a good example how can I use method from One class to another in python and what is significance of __init__ while defining class.
I am using python2.7
Thanks in anticipation.
To use a method defined in one class inside of another class, you have several options:
Create an instance of B from within one of A's methods, then call B's method:
class A:
def methodInA():
b = B()
b.methodInB()
If appropriate, use the concept of inheritance (one of the defining concepts of object-oriented design) to create a subclass of the original class whose method(s) you wish to use:
class B(A):
...
__init__() is a class initializer. Whenever you instantiate an object you are invoking __init__() whether or not it is explicitly defined. It's main purpose is to initialize class data members:
class C:
def __init__(self, name):
self.name = name
def printName(self):
print self.name
c = C("George")
c.printName() # outputs George
With __init__() defined, in particular with the additional argument name in this example, you are able to differentiate between would-be generically constructed instances by allowing for different initial states from instance to instance.
There are 2 issues here:
First: Using method of class A in class B, both classes in different files
class A:
def methodOfA(self):
print "method Of A"
let the above class be in file a.py Now the class B is supposed to be in b.py. Both a.py and b.py are assumed to be on the same level or in the same location. Then b.py would look like:
import a
class B:
def methodOfB(self):
print "Method of B"
a.A().methodOfA()
You can also do this by inherting A in B
import a
class B(a.A):
def methodOfB(self):
print "Method of B"
self.methodOfA()
there are several other ways to use A in B. I will leave it to you to explore.
Now to your second question. The use of __init__ in a class. __init__ is not a constructor, as popularly believed and explained above. It is, as the name suggests, an initialization function. It is called only after the object has already been constructed and it is implicitly passed the object instance as the first argument, as signified by self in its argument list.
The actual constructor in python is called __new__, which does not need a object to call it. This is actually a specialized Static method, which receives the class instance as the first argument. __new__ is exposed for overwriting only if the class inherits form the object base class of python
Whatever other arguments are passed while creating an object of a class, first go to __new__ and then are passed with the object instance to the __init__, if it accepts them.
The init function is what is called a constructor function. When you create an instance of a class object = myClass(), init is the function that is automatically called. i.e.
That being said, to call a function from one class to another, you need to call an instance of the second class inside the first one, or vice versa. for eg.
class One():
def func(self):
#does sometthing here
class Two():
def __init__(self):
self.anotherClass = One()
#Now you can access the functions of the first class by using anotherClass followed by dot operator
self.anotherClass.func()
#When you call the main class. This is the time the __init__ function is automatically called
mainClass = Two()
Another way to access from another class is the use of oop concept called Inheritance.
class One():
def __init__(self):
print('Class One Called')
def func(self):
print('func1 Called')
class Two(One):
def __init__(self):
One.__init__(self,) #This basically creates One's instance
print('Main Called')
c= Two()
c.func()
The output for this is:
Class One Called
Main Called
func1 Called
class Grid(QFrame):
def generate(self):
self.pen = False
self.tgDig = False
self.rwDig = False
I'm not sure how this works.
The generate method is defined with self as a parameter and I understand that all methods must have a special first parameter, usually called self but I don't understand how the self invokes pen or tgDig or rwDig since they don't exist anywhere else?
It's using PyQt QFrame if that helps.
All the methods of a class in Python have as first parameter self, which is a reference to the object itself. Like this in Java or C++. So in your example the three variables are members of the class, and you accesses it with self.
In your concrete example, you do not see the variables in the class because they are inherited from another class (QFrame). The syntax for a class to inherit from another is class MyClass(ParentClass)
self is refering to the object that owns the method generate, it looks like pen, tgDig, and rwDig are also members of this same class or its parent class in the case of inheritance (etc. etc.).
this might be of some use.
If you run the examples you will see the method resolution order and the base class that Grid inherits its attributes and methods from.
import sys
app = QApplication(sys.argv)#
from PyQt4.QtGui import QFrame,QApplication
class Grid(QFrame):
def generate(self):
self.pen = False
self.tgDig = False
self.rwDig = False
import inspect
print inspect.getmro(Grid)
print(Grid.__bases__)
This simple example is what I dont get to work or understand in my more complex script:
class printclass():
string="yes"
def dotheprint(self):
print self.string
dotheprint(self)
printclass()
When the class is called, I expected it to run the function, but instead it will tell me that "self is not defined". Im aware this happens on the line:
dotheprint(self)
But I dont understand why. What should I change for the class to run the function with the data it already has within? (string)
You misunderstand how classes work. You put your call inside the class definition body; there is no instance at that time, there is no self.
Call the method on the instance:
instance = printclass()
instance.dotheprint()
Now the dotheprint() method is bound, there is an instance for self to refer to.
If you need dotheprint() to be called when you create an instance, give the class an __init__ method. This method (the initializer) is called whenever you create an instance:
class printclass():
string="yes"
def __init__(self):
self.dotheprint()
def dotheprint(self):
print self.string
printclass()
You really need to understand Object-Oriented Programming and its implementation in Python.
You cannot "call" a class like any function. You have to create an instance, which has a lifetime and methods linked to it :
o = printclass() # new object printclass
o.dotheprint() #
A better implementation of your class
class printclass():
string="yes" #beware, this is instance-independant (except if modified later on)
def dotheprint(self):
print self.string
def __init__(self): # it's an initializer, a method called right after the constructor
self.dotheprint()
You'll have to forgive me, I am trying to teach myself OO but I have come across this problem with composition and 'has-a' relationships.
class Main(object):
def A(self):
print 'Hello'
def B(self):
self.feature = DoSomething()
class DoSomething(object):
def ModifyMain(self):
#Not sure what goes here... something like
Main.A()
def run():
M = Main()
M.B()
A real world example of the above simplification is a PySide application where Main is a MainWindow, and DoSomething is a dynamically created widget that is placed somewhere in the window. I would like DoSomething to be able to modify the status bar of the mainwindow, which is essentially calling (in Main) self.statusbar().
If there is a shortcut in PySide to do this, Tops!! please let me know! However, I'm actually after the more general Pythonic way to do this.
I think I'm close ... I just can't make it work...
Why don't you use a signal and slot instead? That's a more Qt and OOP way of doing this.
In your dynamically created widget class:
self.modifyMain = QtCore.Signal(str)
In your main class:
#QtCore.Slot(str)
def changeStatusbar(self, newmessage):
statusBar().showMessage(newmessage)
in you main class after creating your widget:
doSomething.modifyMain.connect(self.changeStatusbar)
And in you widget class, where you want to change the statusbar of main, you say:
modifyMain.emit("Hello")
None of this is tested as I don't have a PySide installation handy.
There are two problems with your code:
At no time do you call ModifyMain; and
Main.A() will result in an error, because A is an instance method, but you are calling it on a class.
You want something like:
class Main(object):
def A(self):
print 'Hello'
def B(self):
self.feature = DoSomething() # self.feature is an instance of DoSomething
self.feature.ModifyMain(self) # pass self to a method
class DoSomething(object):
def ModifyMain(self, main): # note that self is *this* object; main is the object passed in, which was self in the caller
#Note case - main, not Main
main.A()
def run():
M = Main()
M.B()
if __name__=="__main__": # this will be true if this script is run from the shell OR pasted into the interpreter
run()
Your names all flout the usual python conventions found in PEP8, which is a pretty good guide to python style. I have left them as they were in your code, but don't copy the style in this example - follow PEP8.