如何从另一个类调用一个类的方法?

问题描述:

我想调用另一个类的类的方法。我想要做这样的事情。如何从另一个类调用一个类的方法?

class A: 
    def meth(self): 
     B.meth1() 

class B: 
    def meth1(self): 
     pass 

a = A() 
a.meth() 

我得到以下错误:

TypeError: unbound method meth1() must be called with B instance as first argument (got nothing instead) 

我在做什么错?

更新:

上面的例子是可能有点模糊。这就是我究竟打算做:

class A: 
    def meth(self, data): 
     if data[0] == '/': 
      B.handleCOMMAND(data) 

class B: 
    def handleCOMMAND(self, data): 
     """ 
     Some code to handle some command. 
     """ 

更新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' 

我面临的主要问题是:

'self.state' 是一个实例变量类B.根据类A的meth()的数据获取,需要调用B类的句柄COMMAND,它应该改变'self.state'的值。

+3

你想要的效果是什么?通常情况下,'B'方法需要一个'B'实例来工作,但是如果你从'A'调用,那么你没有'B'实例。 (如果'B.meth1'不需要实例,则改为classmethod,如果它甚至不需要该类,则将其从类中取出并使其成为函数。) – BrenBarn 2013-04-23 20:28:56

+0

如果您只是希望能够为A类使用B类方法之一,您应该为此使用[inheritance](http://docs.python.org/2/tutorial/classes.html)。这是你想要的吗? – 2013-04-23 20:32:05

+1

也许你想'B.meth1'成为'staticmethod'?没有更多细节,确实很难知道任何事情。 – mgilson 2013-04-23 20:32:09

你不能调用实例方法,除非你有一个实例调用它。

不知道你的设计目标是什么,不可能告诉你实例应该来自哪里,但有两种特别常见的模式。

首先,该方法可能需要一个B实例作为参数。例如:

class A: 
    def meth(self, b): 
     b.meth1() 

class B: 
    def meth1(self): 
     pass 

a = A() 
b = B() 
a.meth(b) 

为了使这更具体,想象ACar,并BTollRoad,并my_car.drive(my_road)还打电话叫my_road.pay_toll()


或者,每个A实例可以拥有一个B实例作为构件。例如:

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

为了使这更具体,想象ACar又和B是ServiceCenter和my_car.schedule_service()需要调用my_car.service_center.get_next_appointment()


至于后者的变型中,每个B实例可以是类的部分的最全的A实例的,由A实例自动构造。例如:

class A: 
    def __init__(self): 
     self.b = B() 
    def meth(self): 
     self.b.meth1() 

class B: 
    def meth1(self): 
     pass 

a = A() 
a.meth() 

对于这一个,想象ACar又和BEngine。因此,my_car.drive()开始拨打my_car.engine.start()。但是,不像ServiceCenter,这是一个独立生活并被许多汽车使用的东西,Engine仅用于它所属的汽车,因此没有理由分开创建发动机并将其传递给汽车(除非你正在模拟一家汽车厂)。

class A: 
    def meth(self): 
     "create instance of B class" 
     b = B() 
     b.meth1() 

您也可以声明B.meth1()为静态:

class B: 
    @staticmethod 
    def meth1(): 
     pass 

然后,你可以这样调用:

class A: 
    def meth(self): 
     "create instance of B class" 
     B.meth1() 
+1

这确实消除了错误,但它可能不是OP实际想要做的。 – abarnert 2013-04-23 20:30:08

+0

检查我的更新。我已经提到了静态方法,现在也是 – hek2mgl 2013-04-23 20:34:36

+0

而这甚至可能是他想要的。 '@ staticmethod'没有太多好用处。 (当然有_some_--但是如果新手认为他想要一个'staticmethod',他可能想要重新考虑他的设计。) – abarnert 2013-04-23 20:37:04

这里B.meth1是实例方法和您正试图使用​​它作为类方法。您可以重新定义B.meth1是一个类方法:

class B: 
    @classmethod 
    def meth1(cls): 
    pass 

或者,你可以把它作为一个实例方法通过实例化B级:

class A: 
    def meth(self): 
     B().meth1() 
+0

这与hek2mgl的答案非常相似,它也有相同的问题:它将摆脱错误,但它可能不会做OP希望做的事情(除非他有一个不寻常的用例或不好的设计)。 – abarnert 2013-04-23 20:34:26

B被用作静态类。

class A: 
    def meth(self): 
     B.meth1() 

class B: 
    @staticmethod 
    def meth1(): 
     pass 

a = A() 
a.meth() 
+1

我不确定为什么这会得到提高,因为有两个较早的答案说完全相同的事情,更多的解释。但是,与这两者一样,这可能不是OP想要的 - 或者,如果是的话,他可能不应该需要它。 – abarnert 2013-04-23 20:43:57