python class instance method call from another class instance - python

I have a quick question regarding python classes.
The following is the setup:
I have one class as the "mastermind" class which contains various instances of other classes. Now these classes need to call a method of that other class, but I don't know how to do that. For example:
class mastermind(object):
def __init__(self):
self.hand = hand()
def iNeedToCallThisMethod(self, funzies):
print funzies
class hand(object):
def __init(self):
pass #here should be a call to the mastermind instance's method
example = mastermind()
Hope you guys can help me with that, my brain is steaming! Thanks a lot!

If you want to call mastermind's method, you need to have a reference to it.
For example
class mastermind(object):
def __init__(self):
self.hand = hand(self)
def iNeedToCallThisMethod(self, funzies):
print funzies
class hand(object):
def __init__(self, mastermind)
mastermind.iNeedToCallThisMethod('funzies')

If you need to call iNeedToCallThisMethod from the __init__ of hand, you should probably put the method in that class.
However, what you want to do can be achieved using a classmethod:
class mastermind(object):
def __init__(self):
self.hand = hand()
#classmethod
def iNeedToCallThisMethod(cls, funzies):
print funzies
class hand(object):
def __init__(self):
mastermind.iNeedToCallThisMethod('funzies')
example = mastermind()

Both object need a reference to one another, try passing the instance to the constructor.
class Mastermind(object):
def __init__(self):
self.hand = Hand(self)
def test_funct(self, arg):
print arg
class Hand(object):
def __init(self, mastermind):
self.mastermind = mastermind
self.mastermind.test_funct()

class hand(object):
def __init(self, other_class):
#here should be a call to the mastermind instance's method
other_class.iNeedToCallThisMethod()
m_m = mastermind()
example = hand(m_m) # passes mastermind to new instance of hand
I'd just pass the object like above

Related

How can I implement a method to print an object in the super class?

When I run this, I get the desired string corresponding to the species object that is created. My goal here is to be able to create a method called speak in the Animal class that achieves the same thing. But I don't have a good understanding on how to do that.
class Animal(object):
def __init__(self):
pass
def speak():
pass
class Mammal(Animal):
def __init__(self):
Animal.__init__(self)
class Cat(Mammal):
def __init__(self):
Mammal.__init__(self)
def __str__(self):
return "meeeow"
class Dog(Mammal):
def __init__(self):
Mammal.__init__(self)
def __str__(self):
return "wooof"
class Primate(Mammal):
def __init__(self):
Mammal.__init__(self)
class Hacker(Primate):
def __init__(self):
Primate.__init__(self)
def __str__(self):
return "Hello world!"
garfield = Cat()
print(garfield)
spike = Dog()
print(spike)
john = Hacker()
print(john)
Yours inherited classes can access any method defined in the parent class. So to achieve this, just define a new method called speak in Animal class and print as you did in your examples:
class Animal(object):
def __init__(self):
print(self)
pass
def speak(self):
print(self)
Then just create the instance and call the function:
garfield = Cat()
garfield.speak()
Output
meeeow
Modify your Animal class like below. When you call the super method from your subclass, you're passing the instance of the class you created to the parent's init function. So the instance of class is passed to the Mammal init function, which calls super and passes the instance to the Animal init function.
class Animal(object):
def __init__(self):
self.speak()
def speak(self):
print(self)

python accessing variable of high level from lower level class

I have a class inside a class like this:
class Robot(object):
def __init__(self):
self.name = 'ganken'
class Speaker(object):
pass
Let’s say I want to access Robot.name from Speaker, how do I do that
You can make Speaker a sub class of Robot:
class Robot(object):
def __init__(self):
self.name = 'ganken'
class Speaker(Robot):
def get_name(self):
return self.name
When you make an instance of Speaker, it will now have the name ganken associated with it.
s = Speaker
s.get_name()
Output:
'ganken'
You could have also called s.name and it would have still returned 'ganken', but usually you want to define functions in your class to get and set different attributes of your class (look up getters and setters if you want more information).
I might have misunderstood your question. If you want to access the name of a instance of a Robot class in your Speaker class (and don't necessarily want to make Speaker a subclass of Robot), you could define your class as:
class Robot(object):
def __init__(self):
self.name = 'ganken'
class Speaker(object):
def get_robot_name(self, robot):
return robot.name
Notice that you can pass a robot instance into the get_robot_name function in this example.
Demo:
r = Robot()
s = Speaker()
s.get_robot_name(r)
'ganken'
You could try the following where you create a speaker object in the Robot class if you are looking for a nested class solution. But i don't know what is the reason for you to do this though.
Try this assuming Python3 environment:
class Robot(object):
def __init__(self):
self.name = 'ganken'
self.speaker = self.createSpeaker()
def createSpeaker(self):
return Robot.Speaker(self)
class Speaker:
def __init__(self,robot):
self.robot = robot
def say_name(self):
return f'Name: {self.robot.name}'
robot = Robot()
print(robot.speaker.say_name())
Try the below:
print(Robot().name)
Just call it then access it
Output is:
ganken

How to use super() to update a value in a specific instance of the parent?

I want to use the super function to write a string into a list of a specific instance of a parent object. Here's my code so far:
#!/usr/bin/env python
# test.py
class Master(object):
def __init__(self):
pass
class Sub1(Master):
list = []
def __init__(self):
pass
class Sub2(Sub1):
def __init__(self, name):
super(Sub2, self).list.append(name)
m = Master()
m.foo = Sub1()
m.foo.bar = Sub2('something')
m.bla = Sub1()
m.bla.blub = Sub2('else')
print(m.foo.list)
In this case the output is of course
['something', 'else']
However I want it to be just 'something'.
How can I achieve this?
I tried:
class Sub1(Master):
def __init__(self):
self.list = []
Which yields:
AttributeError: 'super' object has no attribute 'list'
Is there an easy solution?
As you have noted, if you define lst as a class attribute in Sub1, it is shared among all instances, which is not what you want. So you have to define lst as an instance attribute in Sub1 but then it has to be managed by an instance of Sub1 and not an instance of Sub2. Here is a modified code that offers what you expect:
class Master(object):
def __init__(self):
super().__init__()
class Sub1(Master):
def __init__(self):
super().__init__()
self.lst = []
def add(self, item):
self.lst.append(item.name)
class Sub2(Sub1):
def __init__(self, name):
super().__init__()
self.name = name
m = Master()
m.foo = Sub1()
m.foo.add(Sub2('something'))
m.bla = Sub1()
m.bla.add(Sub2('else'))
print(m.foo.lst)
print(m.bla.lst)
Here is the ouput:
['something'] <-- m.foo.lst
['else'] <-- m.bla.lst
Rem1: When using super() the whole class hierarchy has to be collaborative (i.e. use super() in the constructor).
Rem2: In Python3, super() is equivalent to super(classname, self)
Rem3: Don't use list as a variable name (it is a builtin type)
Rem4: My code stores only the name attribute in the list to mimic the example your gave, but I guess that in real life you would rather store instances of Sub2 in that list. To do so, simply remove the .name in the addfunction.
EDIT : Thinking a bit more about my answer, I came to another solution that may be closer to your initial attempt. Let me know which one works best for your actual problem...
class Master(object):
def __init__(self):
super().__init__()
class Sub1(Master):
def __init__(self):
super().__init__()
self.lst = []
class Sub2(Sub1):
def __init__(self, parent, name):
super().__init__()
parent.lst.append(name)
m = Master()
m.foo = Sub1()
m.foo.bar = Sub2(m.foo, 'something')
m.bla = Sub1()
m.bla.blub = Sub2(m.bla, 'else')
print(m.foo.lst)
print(m.bla.lst)
Your actual problem seems to be in the way you initialize list.
You need to assign it in __init__(), not within the class body, to avoid it being shared between all instances of the class (see Static class variables in Python).
class Sub1(Master):
def __init__(self):
self.list = []

Nested classes that inherit from the outer parent's nested classes in Python 3

Suppose I have the following class in Python 3:
class CoolCar:
#classmethod
def myWheels(cls):
cls.Wheels().out()
class Wheels:
def __init__(self):
self.s = "I'm round!"
def out(self):
print(self.s)
All well and good. Now I want a derived class:
class TerribleTank(CoolCar):
class Wheels(CoolCar.Wheels):
def __init__(self):
self.s = "I'm square!!"
This works as I would expect:
CoolCar.myWheels()
TerribleTank.myWheels()
But what's bothering me is that I have to write CoolCar twice in the definition of TerribleTank. So I tried this:
class TerribleTank(CoolCar):
class Wheels(super().Wheels):
def __init__(self):
self.s = "I'm square!!"
Which does not work. Now, I know it doesn't work because super() is looking for a first-argument self/cls to begin its search.
So finally my question: Is there something like this that works, so that I don't need to explicitly write that second CoolCar?
What about:
class CoolCar:
#classmethod
def myWheels(cls):
cls.Wheels().out()
class Wheels:
def __init__(self):
self.s = "I'm round!"
def out(self):
print(self.s)
class TerribleTank(CoolCar):
class Wheels(TerribleTank.Wheels):
def __init__(self):
self.s = "I'm square!!"
>>> TerribleTank.myWheels()
I'm square!!
basically when you inherit CoolCar in TerribleTank, you set up TerribleTank.Wheels as a reference to CoolCar.Wheels, until you shadow it with your own new definition of it within the TerribleTank definition. So I believe that matches your expectations of not having CoolCar twice in TerribleBank definition ☺
HTH

Calling a method's variablename from class A into Class B

I have been searching an answer to my question but could not hit the related answer.
Basically i am trying to call a variable from a Class A thats actually GUI to another Class B my code goes like this:
class CLASSA(wx.Frame):
def Method(self):
self.Var = anyvalue
import CLASSA
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method.Var
i have tried as above but its not working out. Isn't it possible to carry out as mentioned ?
At the very least, you need to actually call CLASSA.Method first:
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method().Var
in order for the Var attribute of the CLASSA object to be initialized.
You do not give enough detail to know if Method is necessary. You could, for instance, simply initialize Var in CLASSA.__init__.
# With recommended capitalization
class A(wx.Frame):
def __init__(self):
self.var = any value
class B(object):
def __init__(self):
sef.var = A().var
It's also possible that B should be a subclass of A, in which case B simply inherits var from A:
>>> class B(A):
... pass
>>> print B().var
anyvalue

Categories