How does this python method invoke work? - python

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__)

Related

Python built-in functions for class object?

I'm new to python. I've heard that everything is an object when it comes to python even if class or function.
As far as I know, the class object is created when the program starts. So I wonder if there's some function for initializing class variables or doing something.
init function can't do because its parameter is self which's for an instance of the class. I want to access the class itself.
class Example():
def __init__(self):
# I know that this function is called when an instance of this class is created
pass
def __something__(cls):
# Is there some function for initializing class object?
# What I wanna do is I want to initialize class variables or call some functions...
# But __init__ function can't do because its parameter is self.
pass
In Python the class object is created at run time as Python is a Dynamic Language.
So if you want to initiate class variables you could just set them right after class definition
class Cls:
cls_var = "before"
print(Cls.cls_var)
Cls.cls_var = "after"
print(Cls.cls_var)
this would print "before" and "after"
you can operate the class you defined directly.
for example, your class name is Example, you can use buildin method dir to see the class method (dir(Example)), use type to see the class type (type(Example)), __dict__ see the class attributes(Example.__dict__) ...

Super and import in python

What are the differences between importing a class from a file and using super() in python?
Import: # I understand that this will import all the functions and init from a class to another class in a file when trigger the below code;
from something import Some
super(): # I understand that this also will inherit all the functions and init from a class to another class in a file. **Ain't this technically the same as importing?
super(xx, self).__init__() or super().__init__() or super()
Can any python experts shows some example? I have recently read some codes online and they used both of this, my question is since both do almost the same thing(to my understanding) then why dont just use either one for all files and why need to use both? If possible, can share some examples?
You'll need to understand a bit of Object-oriented programming principles to understand super.
In general, when you are importing a module, that module becomes available for your current function/class.
By using Super you satisfy inheritance; facilitating your current class's this to have references to all attributes of its parent(s). If you are just developing some functions, you will not need super. This is strictly an object-oriented paradigm.
from xyz import abc
def some_function():
# here you can use abc's attributes by explicit invocation.
x = abc.x
# Or call functions.
abc.some_function()
When you're dealing with classes, super does the magic of facilitating inheritance.
class Parent_Class(object):
def __init__(self):
super(Parent_Class, self).__init__()
def parent_method(self):
print('This is a parent method')
class Child_Class(Parent_Class):
def __init__(self):
super(Child_Class, self).__init__()
def child_method(self):
# Because of super, self of child class is aware of all its parent's methods and properties.
self.parent_method()
import is used for importing module
__init__() is a class method, which is invoked when a new instance of a class is instantiated
This is 2 different thing
EDIT: I've made this edit to clarify the answer for you, since I assume you are not familiar with OOP. TL;DR: These two terms are completely different, they relate to two separate things. super() call a class's parent method, while import import a module
we can still import the module form file B into file A and in file A
we can still use the methods from the file B in file A right?
Right.
what makes it different than super() which calls the methods from file B when used in file A
First, you only encounter super() in subclass (lets say class B) of a class(lets say class A). You access A's method through B's instance via super(). Let see this example: You have 2 file, A.py and B.py, each define A and B:
In A.py, you define class A
class A(object):
def __init__(self):
print("Instantiate class A")
def printA(self):
print("AAAAAAAAAAAAAA")
In B.py, you define class B:
from A import A # you need this import for `B.py` to know what is `A`
class B(A): # Mean B inherit A
def __init__(self):
super(B, self).__init__() # This line all its parent's method (`__init__()`)
def printB(self):
print("BBBBBBBBBBBB")
super(B, self).printA() # This line all its parent's method (`printA`)
# And you instantiate a `B` instance, then call a method of it, which call its super method `printA`
b = B()
b.printB()
Output is (note that `init():
Instantiate class A
BBBBBBBBBBBB
AAAAAAAAAAAAAA
To conclude, I suggest you to read some material about OOP. You will clearly see the differences btw these two things. Good luck. I hope this help!
The import statement is used to import modules into modules. The super callable is used to delegate from subclass implementation to superclass implementation.
Notably, import connects between fixed equals whereas super connects in a dynamic hierarchy.
The point of import is to make a specific module or its content available in another module.
# moda.py
def foo(who):
print(who, "called '%s.foo'" % __name__)
# modb.py
import moda
moda.foo(__name__)
Note that importing uses a qualified name that uniquely identifies the target. At any time, the name used in an import can refer to only one specific entity. That means that import couples strongly - the target is fully identified and cannot change after the import.
The point of super is to access the closest superclass implementation in a subclass implementation.
class A:
def call(self, who):
print(who, "called '%s.call'" % __class__, "on self of class", self.__class__)
class Alpha(A):
def call(self, who):
super(Alpha, self).call(who)
print("... via '%s.call'" % __class__)
Note that super only work with local information - super does only identify the source, not the target. As such, the target is dynamically bound and not uniquely identifiable. That means that super couples weakly - the target is relatively defined and can only be resolved at runtime.
class Alpher(A):
def call(self, who):
print("'%s.call' sneakily intercepts the call..." % __class__)
super(Alpher, self).call(who)
class Better(Alpha, Alpher):
pass
The above injects Alpher into the relation from Alpha to A without modifying either of the two.
>>> Better().call('Saul')
'<class '__main__.Alpher'>.call' sneakily intercepts the call...
Saul called <class '__main__.A'>.call on self of class <class '__main__.Better'>
...via '<class '__main__.Alpha'>.call'

How to set the type of a pyqtSignal (variable of class X) that takes a X instance as argument

I have a pyqtSignal as a class variable and I want its argument to be an instance of that class. How can I declare the type of the argument when I create the signal?
class MyClass(QWidget):
my_signal = pyqtSignal(?)
(...)
def emit_signal(self):
self.my_signal.emit(self)
I know that pyqtSignal(object) would work but I was wondering if there was a sort of __class__ at class-variable level.
Another question: is there a difference between pyqtSignal(MyClass), pyqtSignal(QWidget) (parent class) or pyqtSignal(object)? Performance? I'm asking this question because the types of slot parameters don't seem to matter when we declare them with the #pyqtSlot decorator.
At the moment the Python interpreter interprets my_signal = pyqtSignal(...), the class name is not known to it yet, the class body is created first then it will be assigned to the module variable called MyClass. So the only way to do this is after the class has been defined, and before any attempt is made to access the signal object. This means one of the following two options might work (it depends on how pyqtSignal and QObject work, I can't try it out at this moment):
At module level, after class:
class MyClass(QObject):
def __init__(self, ...):
...
MyClass.my_signal = pyqtSignal(MyClass)
In the init, guarding against re-creation:
class MyClass(QObject):
def __init__(self, ...):
if not hasattr(self, 'my_signal'):
MyClass.my_signal = pyqtSignal(MyClass)

Call a function inside a class when calling the class in python

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()

Adding a method to a class within a class

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

Categories