Python: set variable in one class and use/get in different class - python

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

Related

How to override a function in an inheritance hierarchy?

I would like to implement a widget system similar to FLTK using python in a 3D world.
I simplified my code to the following. I don't get the correct answer. The function is not overwritten even if I change the variable.
def callbacks():
print("callback")
def create():
print ("override")
def default():
print("default")
class f1(object):
def __init__(self):
self.test=default
pass
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
self.test=create
super().__init__()
class f3(f2):
def __init__(self):
self.test=callbacks
super().__init__()
t1=f1()
t2=f2()
t3=f3()
t1.docallback()
t2.docallback()
t3.docallback()
You should be calling super().__init__() first in this case:
class f1(object):
def __init__(self):
self.test = default
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
super().__init__()
self.test = create
class f3(f2):
def __init__(self):
super().__init__()
self.test = callbacks
These 'constructors' call super().__init__() first (which makes assignments to self.test), but then immediately assigns the correct value to self.test itself.
f1.__init__ should use default as the default value of a parameter, not a hard-coded assignment.
class f1:
def __init__(self, test=default):
self.test = test
Then f2 and f3 can simply provide different arguments when using super().
class f2:
def __init__(self):
super().__init__(create)
class f3:
def __init__(self):
super().__init__(callbacks)

defining a var outside of a class used hard in a class giving name error

I created a class using a variable that is declared out side the class and then tried to use that class from a different file. But after using in a different file, defining the variable form that file, I get a name not defined error.
Originally fileOne.py looked like:
dat = 'this string'
class myClass:
def __init__(self):
self.num = 5
def method(self):
return self.num+dat
Now when I change the lay out, so that dat is defined in the other file that calls myClass.
Changed fileOne.py
#dat = 'this string'
class myClass:
def __init__(self):
self.num = 5
def method(self):
return self.num+dat
fileTwo.py
from fileOne import *
dat = "file 2 str"
obj = myClass()
I get back
NameError: name 'dat' is not defined.
I think what I need to do in replace dat with self.dat and pass it as a function parameter. I'm not sure why I'm having this problem.
your class code does not import dat itself.
if you want to use configs in different classes, i suggest the following:
class SystemConfig():
dat = 5
class myClass(SystemConfig):
def __init__(self):
self.num = 5
def method(self):
return self.num + SystemConfig.dat
or from a different file:
from fileone import SystemConfig
class myClass(SystemConfig):
def __init__(self):
self.num = 5
def method(self):
return self.num + SystemConfig.dat
this is much better practice , also lets you run system configuration in one place.

Run a method in initialize after class has been called

I want the results of the method_test() to to be stored in variable a. So that I access it outside my class
class test:
def __init__(self):
a = method()
def method_test():
return "working"
check = test
print(check.a)
You need to set it as an attribute, which can be done with self.a:
class test:
def __init__(self):
self.a = test.method_test()
def method_test():
return "working"
check = test()
print(check.a)
#working
class test:
def __init__(self):
self.a = self.method_test()
def method_test(self):
return "working"
check = test()
print (check.a)

Python: sharing variables between contained class

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?

object inheritance and nested cmd

This is probably a basic OO question:
I'm trying to do a nested console menu with cmd which has gone well.
I also want all my sub-consoles to have access to the same objects. This has not gone well.
My simple Example:
import cmd
class MainConsole(cmd.Cmd):
def __init__(self,obj1,obj2):
cmd.Cmd.__init__(self)
self.prompt = ">"
self.obj1 = obj1 # The objects I want access to in all my consoles.
self.obj2 = obj2
self.menu1 = SubConsole1() # I could pass in the objects here as arguments
self.menu2 = SubConsole2() # but there should be a better way.
def do_menu1(self,args):
self.menu1.cmdloop()
def do_menu2(self,args):
self.menu2.cmdloop()
def do_info(self,args):
self.menu1.do_info(args)
self.menu2.do_info(args)
def do_exit(self,args):
return -1
class SubConsole1(cmd.Cmd,MainConsole):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "1>"
def do_action(self,args):
print self.obj1.someattr1 # Doesn't work
class SubConsole2(cmd.Cmd,MainConsole):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "2>"
def do_action(self,args):
print obj1.someattr2 # Doesn't work
class anobject(object):
def __init__(self,init_value):
self.someattr1 = init_value
self.someattr2 = init_value * 2
object1 = anobject(1)
object2 = anobject(2)
c=MainConsole(object1,object2)
c.cmdloop()
When I run this I get
>
>menu1
1>info
AttributeError: SubConsole1 instance has no attribute 'obj1'
Try again.
>
>menu2
2>info
NameError: global name 'obj1' is not defined
I'm not sure if the SubConsoles should be sub-classes of MainConsole. I also tried nesting the SubConsoles inside of MainConsole.
EDIT Okay, I misunderstood what you're doing.
You are right, SubConsole1 and 2 do not need to inherit from MainConsole. But they should have a reference to the main console.
Something like:
class MainConsole(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self, obj1, obj2)
self.obj1 = obj2
self.obj2 = obj2
class SubConsole1(cmd.Cmd):
def __init__(self, maincon):
cmd.Cmd.__init__(self)
self.maincon = maincon
Then you can access the objects you want by accessing self.maincon.obj1 and self.maincon.obj2
The other option, and probably a better one from a design point of view, is to pull out all the objects you want to access into a Context container object, and have all the various Cmd objects maintain their own reference to that Context container.
Something like this:
import cmd
from collections import namedtuple
class MyConsole(cmd.Cmd):
def __init__(self, context):
cmd.Cmd.__init__(self)
self.context = context
class ConsoleContext(object):
def __init__(self, **kwargs):
self.__dict__ = kwargs
class MainConsole(MyConsole):
def __init__(self, context):
MyConsole.__init__(self, context)
self.menu1 = SubConsole1(context)
self.menu2 = SubConsole2(context)
self.prompt = '>'
def do_menu1(self, args):
self.menu1.cmdloop()
def do_menu2(self, args):
self.menu2.cmdloop()
def do_quit(self, args):
return True
class SubConsole1(MyConsole):
def __init__(self, context):
MyConsole.__init__(self, context)
self.prompt = '1>'
def do_action(self, args):
print self.context.message1
def do_quit(self, args):
return True
class SubConsole2(MyConsole):
def __init__(self, context):
MyConsole.__init__(self, context)
self.prompt = '2>'
def do_action(self, args):
print self.context.message2
def do_quit(self, args):
return True
if __name__ == '__main__':
context = ConsoleContext(message1='Message 1', message2='Message 2')
con = MainConsole(context)
con.cmdloop()
Hope I was clear enough.
You don't need multiple inheritance, but you need to give obj1 and obj2 to the inherited objects, except if you give some default values to obj1 and obj2.
class SubConsole1(MainConsole):
def __init__(self, obb1, obj2):
MainConsole.__init__(self, obj1, obj2)
self.prompt = "1>"
def do_action(self,args):
print self.obj1.someattr1 # Doesn't work
instanciated by :
sub1 = SubConsole1(object1, object2)
The other answer is correct insofar as you should not be using multiple inherritance, as the following is true:
class A(object):
pass
class B(A):
pass
class C(A):
pass
class D(B):
pass
a = A()
b = B()
c = C()
d = D()
isTrue = isinstance(a,A) and isinstance(b,A) and isinstance(c,A) and isinstance(d,A)
isTrue = isTrue and isinstance(b,B)and isinstance(d,B)
isTrue = isTrue and isinstance(c,C)
isTrue = isTrue and isinstance(d,D)
>>> print isTrue
True
It would also be wise to create a method of your main class wich creates subcmds, passing their reference to the subcmd's __init__ function. This way you have your object spawn its children more naturally.
class MainConsole(cmd.Cmd):
def spawnsubconsole(self):
return SubConsole1(self)
def __init__(self):
cmd.Cmd.__init__(self, obj1, obj2)
self.obj1 = obj2
self.obj2 = obj2
class SubConsole1(cmd.Cmd):
def __init__(self, maincon):
cmd.Cmd.__init__(self)
self.maincon = maincon
Then you can access the objects you want by accessing self.maincon.obj1 and self.maincon.obj2 and get the sub-cmd by running maincon.spawnsubconsole() assuming maincon is an instance of the main console class.

Categories

Resources