i have one class
class worker:
def __init__(self, mainProject, victims):
self.mainProject = mainProject
self.victims = victims
def mainWork(self, mainProject, victims):
...
def send(self):
...
in mainWork() i define some vars, browser object and other data, i need to transfer them to send()
Just assign and read whatever you want in self:
def mainWork(self, mainProject, victims):
self.whatever = 42
def send(self):
print self.whatever
do something like this:-
class worker:
def __init__(self, mainProject, victims):
self.mainProject = mainProject
self.victims = victims
def send(self):
print self.mainProject, self.victims
def main():
w = worker('programming', 'Jess')
w.send()
if __name__ == '__main__':
main()
Related
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)
I would like to implement a parent class decorator in my child class whose functionality depends on the state of the child class instance. I've tried coming at this problem from three different angles, none of which have worked:
Parent method
If give_feedback is a static method, there's no self within the method. But if it's an instance method, there's no self within the namespace in which it's applied.
class Interface:
def __init__(self, quiet=False):
self.quiet = quiet
def echo(self, text):
if not self.quiet:
print(text)
def give_feedback(self, func):
def wrapper(*args):
print('Calling give_feedback.')
self.echo(func(*args))
return wrapper
class App(Interface):
#Interface.give_feedback # self not defined here.
def app_func(self, num):
feedback = 'Success with {num}'.format(num=num)
return feedback
if __name__ == '__main__':
a = App()
a.app_func(3)
Parent class using __call__ (cf. link example_1)
Can't access the object from within __call__.
class Interface:
# ...
class give_feedback:
def __init__(self, func):
self.func = func
def __call__(self, *args):
print(
'Calling {func}'.format(func=self.func)
)
instance = get_obj_instance(self.func) # What is this?
return instance.echo(self.func(instance, *args))
class App(Interface):
# ...
if __name__ == '__main__':
# ...
Parent descriptor (cf. link example_2)
Can access the object, but no arguments.
class Interface:
# ...
class give_feedback:
# ...
def __get__(self, instance, owner):
print(
'Getting {func} from {inst} of {ownr}'.format(
func=self.func, inst=instance, ownr=owner
)
)
num = 2 # How to get num???
return instance.echo(self.func(instance, num))
class App(Interface):
# ...
if __name__ == '__main__':
a = App()
a.app_func # No ability to pass parameters.
Is there a good way to do this?
Why not combine the 2nd and 3rd methods? Use __get__ to get the class instance, and __call__ to decorate with echo. Rather than returning app_func, return a new object that holds the instance and has the desired __call__ behavior.
class Interface:
def __init__(self, quiet=False):
self.quiet = quiet
def echo(self, text):
if not self.quiet:
print(text)
class give_feedback:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.InstHolder(instance, self.func)
class InstHolder:
def __init__(self, inst, func):
self.inst = inst
self.func = func
def __call__(self, *args):
return self.inst.echo(self.func(self.inst, *args))
class App(Interface):
#Interface.give_feedback
def app_func(self, num):
feedback = 'Success with {num}'.format(num=num)
return feedback
if __name__ == '__main__':
a = App()
a.app_func(3)
a.quiet = True
a.app_func(4)
How could I modify the class Auto, to make sure the main work?
class Tool:
def __init__(self, target):
self.target = target
class Wifi:
def __init__(self):
pass
def connect(self, id):
print id
self.target.write("xxxxxxxxx")
def verify(self)
pass
if __name__ == '__main__':
T = Tool(target)
T.Wifi.connect("dev")
I want to imitate the module like redmine:
from redmine import Redmine
redmine = Redmine(REDMINE_URL, key = REDMINE_API_KEY)
redmine.issue.get('16520')
This is not done with nested classes but with composition:
class Tool:
def __init__(self, target):
self.target = target
self.wifi = Wifi(self.target)
class Wifi:
def __init__(self, target):
self.target = target
def connect(self, id):
print id
self.target.write("xxxxxxxxx")
def verify(self)
pass
if __name__ == '__main__':
T = Tool(target)
T.wifi.connect("dev")
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?
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.