Reputation: 4237
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'
Upvotes: 0
Views: 360
Reputation: 365717
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).
Upvotes: 4
Reputation: 3500
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()
Upvotes: 1
Reputation: 6623
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()
Upvotes: 0
Reputation: 157990
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()
Upvotes: 0