I'm trying to use a variable from one class in another, but I get the error, "run() missing 1 required positional argument: 'MyWindowClass'"
class TaskThread(QtCore.QThread):
updateProgressSignal = QtCore.pyqtSignal(int)
def run(self, MyWindowClass):
for i in range(101):
self.updateProgressSignal.emit(i)
print ( MyWindowClass.pbTimeUpdate )
time.sleep(MyWindowClass.pbTimeUpdate)
class MyWindowClass(QtGui.QDialog ):
def __init__(self, *args):
super(MyWindowClass, self).__init__(*args)
self.pbTimeUpdate = .2
self.myLongTask = TaskThread()
self.myLongTask.updateProgressSignal.connect (self.onProgress)
self.myLongTask.start()
def onProgress (self, val )
print (val)
I've tried making the variable global (declared outside both classes in same file), but updating the variable value in in one class, the other class still sees the original value)
What could be the issue?
This should work:
class MyWindowClass(QtGui.QDialog):
pbTimeUpdate = .2
class TaskThread(QtCore.QThread):
updateProgressSignal = QtCore.pyqtSignal(int)
def run(self):
for i in range(101):
self.updateProgressSignal.emit(i)
print(MyWindowClass.pbTimeUpdate)
time.sleep(MyWindowClass.pbTimeUpdate)
Related
I was wondering if there is a method of calling a variable from another class below from the above without switching its position.
class First(Second, Third):
def __init__(self):
super().__init__()
self.num1 = 1
# add num
def add_nums(self):
print(self.num1 + self.set_num2() + self.set_num3())
#Second class
class Second:
def __init__(self):
self.num2 = 2
# Set num
def set_num2(self):
return self.num2
# Third class
class Third:
def __init__(self):
self.num3 = 3
def set_num3(self):
return self.num3
On the above, without changing the position of classes, is there a way to call the second and third class function output.
I am new in Python, please ignore my explanation mentioned below, Basically I want a middle class(setter/getter) so that I can set values in one class and get values from any other class. I tried to make small program just for the solution purpose.
I am setting variable in class A
import sg
import testB
class A():
def __init__(self):
self.s = sg.SG()
def run(self):
self.s.setTest('123')
testB.B().run()
A().run()
using set get method class:
class SG():
test = ''
def __init__(self):
self.test = ''
print('I am in init')
def setTest(self, test1):
print('I am in set')
self.test = test1
def getTest(self):
print('I am in get')
return self.test
trying to retrieve variable value in class B:
import sg
class B():
def __init__(self):
pass
# self.s = sg.SG()
def run(self):
print("i am in B run")
sg.SG.getTest()
I have the following code:
class Person:
def __init__(self,name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = vale
def setName(self, name):
self.name = name
class Main:
def __init__(self):
self.people = []
def addPerson(self,name):
self.people.append(Person(name))
def updateBalance(self,balance,index):
self.people[index].setBalance(50)
print self.people[0]
main = Main()
main.addPerson("Jack")
main.updateBalance(30,0)
I made the following code just to see how objects works with array. But, when I try to run it I get NameError: name 'self' is not defined. I'm not sure what I'm doing wrong ?
If something is not clear or needs editing then please let me know in the comments before down voting.
Many thanks
There a several issues with your code:
Class methods, need to refer to the class def ...(self, ...)
print(...) is a function in Python3 and has to be called from within a method.
The following adjustments make your code work:
class Person:
def __init__(self, name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = value
def setName(self, name):
self.name = name
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance, index):
self.people[index].setBalance(50)
print("Updating people at index %d" % index)
main = Main()
main.addPerson("Jack")
main.updateBalance(30, 0)
print (main.people[0])
Prints:
Updating people at index 0
<__main__.Person instance at 0x100d065f0>
You should pass self as a parameter as well:
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance,index):
self.people[index].setBalance(50)
print people[0] #no need for self if you are calling local variable of class but this will print an empty array
Also you have type error
class Person:
def __init__(self,name):
self.name = name
self.balance = 0
def setBalance(self, value):
self.balance = vale --> not vale but value
def setName(self, name):
self.name = name
Whereas languages like Java or C++ make the "self"/"this" argument implicit in their method definitions, Python makes it explicit. So, the method definitions in your Main class should look like this:
class Main:
def __init__(self):
self.people = []
def addPerson(self, name):
self.people.append(Person(name))
def updateBalance(self, balance, index):
self.people[index].setBalance(50)
In effect, what you had before was an addPerson() method that accepted zero arguments from the caller... and it had renamed self to name, quite unintuitively. Calling the first parameter to a method "self" in Python is only by convention... you could just as easily define addPerson() like this:
class Main:
def addPerson(something_other_t_self, name):
something_other_than_self.people.append(Person(name))
...and it would work exactly the same.
I am implementing a python class, which constructs another object in the constructor whose type is determined based on the parameter passed to it. For example in the code below "workerA" has the behavior of class "MyAClass" and "workerB" object has the behavior of "MyBClass".
I am using this method instead of deriving different class from the base class because the BaseClass is already being used in a different code which cannot be changed. So if I want another behavior of BaseClass as for "MyBClass" behavior then I only need to passed the parameter dbtype = "MyBClass" to it.
Is there any better method which can be used and which gives the same result?
import sys
# MyAClass definition
class MyAClass :
def __init__(self, serverSettings):
self._serverSettings = serverSettings
def initialize(self):
self._init = 1;
print("Calling", sys._getframe(1).f_code.co_name)
def add(self):
self._init = 2;
print("Calling", sys._getframe(1).f_code.co_name)
def finalize(self):
self._init = 3;
print("Calling", sys._getframe(1).f_code.co_name)
def __del__(self):
print('Calling destructor of class ', self.__class__.__name__)
# MyBClass definition
class MyBClass :
def __init__(self, serverSettings):
self._serverSettings = serverSettings
def initialize(self):
self._init = 1;
print("Calling", sys._getframe(1).f_code.co_name)
def add(self):
self._init = 2;
print("Calling", sys._getframe(1).f_code.co_name)
def finalize(self):
self._init = 3;
print("Calling", sys._getframe(1).f_code.co_name)
def __del__(self):
print('Calling destructor of class ', self.__class__.__name__)
# The base class which will be called in main program
class BaseClass :
def __init__(self, serverSettings, dbtype = None):
if(dbtype == None):
self.__worker = MyAClass(serverSettings)
elif(dbtype == "MyBClass") :
self.__worker = MyBClass(serverSettings)
else :
print("Undefined type")
def initialize(self):
self.__worker.initialize()
def add(self):
self.__worker.add()
def finalize(self):
self.__worker.finalize()
if __name__ == "__main__":
serverSettings = dict()
serverSettings["address"] = "localhost"
serverSettings["name"] = "Testname"
workerA = BaseClass(serverSettings)
workerA.add()
workerB = BaseClass(serverSettings, dbtype = "MyBClass")
workerB.finalize()
I know this doesn't produce the same output as your original program, but would something like this work for your purposes? Unless you're querying the method name (as you are above), you should get functionally identical results.
class BaseClass :
def __init__(self, serverSettings, dbtype=None):
if(dbtype == None):
self.__worker = MyAClass(serverSettings)
elif(dbtype == "MyBClass") :
self.__worker = MyBClass(serverSettings)
else :
print("Undefined type")
def __getattribute__(self, x):
settings = object.__getattribute__(self, '__dict__').get('_BaseClass__worker')
return settings.__getattribute__(x)
Alternately, using some class twizzing like this:
class BaseClass :
def __init__(self, serverSettings, dbtype='MyAClass'):
dbtypes = {'MyAClass': MyAClass,
'MyBClass': MyBClass}
if dbtype not in dbtypes:
raise("Undefined type")
self.__class__ = dbtypes[dbtype]
self.__init__(serverSettings)
I made the following code changes based on the suggestions
class BaseClass :
def __init__(self, serverSettings, Classtype = MyAClass):
authclasses = [MyAClass, MyBClass]
if Classtype not in authclasses :
self.__worker = MyAClass(serverSettings)
else :
self.__worker = MyBClass(serverSettings)
def __getattribute__(self, x):
settings = object.__getattribute__(self, '__dict__').get('_BaseClass__worker')
return settings.__getattribute__(x)
Is there a way to share member variables between a class and a nested class ?
for example
class Base(object):
class __Internal(object):
def __init__(self, parent):
self.__parent = parent
self.__parent.__private_method()
#
def __init__(self):
self.__internal = Base.__Internal(self)
return
def __private_method(self):
print "hurray"
return
if name == "main":
b = Base()`
is there a way for the __Internal class to access members of the parent class ?
iam looking for private members like parent.__vars/__methods .
I have edited the code to better explain this. running this code throws
AttributeError: 'Base' object has no attribute '_Internal__private_method'
To access privete method, instead of this:
self.__parent.__private_method()
use this:
self.__parent._Base__private_method()
Modified your example:
class Base(object):
class __Internal(object):
def __init__(self, parent):
self.__parent = parent
self.__parent._Base__private_method()
def __init__(self):
self.__internal = Base.__Internal(self)
return
def __private_method(self):
print "hurray"
return
if __name__ == "__main__":
b = Base()
It results in:
hurray
You must use BaseClassName.methodname(self, arguments) or BaseClassName.field
Example (very ugly code):
class Base(object):
some_field = "OK"
class Internal(object):
def __init__(self, parent):
self.__parent = parent
def change_some_field(self):
Base.some_field = "NOP"
def __init__(self):
self.__private = "val"
self.__internal = Base.Internal(self)
def show_field(self):
print self.some_field
def change_some_field(self):
self.__internal.change_some_field()
def main():
a = Base()
a.show_field()
a.change_some_field()
a.show_field()
return 0
if __name__ == '__main__':
main()
You can find a very useful resources at Why are Python's 'private' methods not actually private?