I want to call a method of a class from another class. I'd like to do something like this.
class A:
def meth(self):
B.meth1()
class B:
def meth1(self):
pass
a = A()
a.meth()
I get the following error :
TypeError: unbound method meth1() must be called with B instance as first argument (got nothing instead)
What am I doing wrong?
Update:
The example above is probably a bit vague. Here's what I exactly intend to do :
class A:
def meth(self, data):
if data[0] == '/':
B.handleCOMMAND(data)
class B:
def handleCOMMAND(self, data):
"""
Some code to handle some command.
"""
Update 2:
class A:
def meth(self, data):
if data[0] == '/':
B.handleCOMMAND(data)
class B:
def __init__(self):
self.state = 'CHAT'
def handleCOMMAND(self, data):
if data.strip().split()[1] == 'send':
self.state == 'RECV-FILE'
The main problem I am facing is that :
'self.state' is an instance variable in class B. And depending on what 'data' meth() of class A gets, handleCOMMAND of class B needs to be invoked which is supposed to alter the value of 'self.state'
4 Answers 4
You can't call an instance method unless you have an instance to call it on.
Without knowing what your design goals are, it's impossible to tell you where the instance should come from, but there are two particularly common patterns.
First, the method might take a B instance as a parameter. For example:
class A:
def meth(self, b):
b.meth1()
class B:
def meth1(self):
pass
a = A()
b = B()
a.meth(b)
To make this more concrete, imagine that A is a Car, and B is a TollRoad, and my_car.drive(my_road) has to call my_road.pay_toll().
Alternatively, each A instance may own a B instance as a member. For example:
class A:
def __init__(self, b):
self.b = b
def meth(self):
self.b.meth1()
class B:
def meth1(self):
pass
b = B()
a = A(b)
a.meth()
To make this more concrete, imagine that A is a Car again, and B is a ServiceCenter, and my_car.schedule_service() needs to call my_car.service_center.get_next_appointment().
As a variation to the latter, each B instance may be a sort of part-of-the-whole of an A instance, constructed automatically by the A instance. For example:
class A:
def __init__(self):
self.b = B()
def meth(self):
self.b.meth1()
class B:
def meth1(self):
pass
a = A()
a.meth()
For this one, imagine that A is a Car again, and B is an Engine. So, my_car.drive() starts off calling my_car.engine.start(). But, unlike a ServiceCenter, which is a thing that lives on its own and is used by many cars, an Engine is only used by the car it's part of, so there's no good reason to create the engine separately and pass it to the car (unless you're modeling a car factory).
Comments
B is being used as a static class.
class A:
def meth(self):
B.meth1()
class B:
@staticmethod
def meth1():
pass
a = A()
a.meth()
1 Comment
class A:
def meth(self):
"create instance of B class"
b = B()
b.meth1()
Also you can declare B.meth1() as static:
class B:
@staticmethod
def meth1():
pass
Then you can call it like this:
class A:
def meth(self):
"create instance of B class"
B.meth1()
3 Comments
@staticmethods. (Of course there are _some_—but it's uncommon enough that if a novice thinks he wants a staticmethod he probably wants to rethink his design.)Here B.meth1 is an instance method, and you are attempting to use it as a class method. You can either re-define B.meth1 to be a classmethod:
class B:
@classmethod
def meth1(cls):
pass
Or, you can call it as an instance method by instantiating the B class:
class A:
def meth(self):
B().meth1()
Bmethod needs aBinstance to work, but if you're calling fromA, you don't have aBinstance. (IfB.meth1doesn't need an instance, make it a classmethod instead. If it doesn't even need the class, take it out of the class and make it a function.)B.meth1to be astaticmethod? Without more details, it's really hard to know anything for sure.