2013-04-23 168 views
0

我想調用另一個類的類的方法。我想要做這樣的事情。如何從另一個類調用一個類的方法?

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

回答

4

你不能調用實例方法,除非你有一個實例調用它。

不知道你的設計目標是什麼,不可能告訴你實例應該來自哪裏,但有兩種特別常見的模式。

首先,該方法可能需要一個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僅用於它所屬的汽車,因此沒有理由分開創建發動機並將其傳遞給汽車(除非你正在模擬一家汽車廠)。

0
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

0

這裏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

1

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