2016-02-09 33 views
0

我正在編寫一個服務器應用程序,該功能是通過RPC調用的。應用程序具有可以相互交互的對象。如何聲明哪些方法可以應用於哪些對象

假定以下簡化的例子:

  • 人員可以檢查和修復,以及可以檢查;
  • 汽車可以剎車,並且可以檢查和固定。

直接實現¹(RPC超出範圍):

class Car(object): 
    def __init__(self, broken=False): 
     self.name = 'car' 
     self.broken = broken 

    def breaks(self): 
     self.broken = True 
     print 'Car broke' 

    def inspected(self, by): 
     if by.pro: 
      if self.broken: 
       print '{}: It\'s a broken car'.format(by.name) 
      else: 
       print '{}: It\'s a working car'.format(by.name) 
     else: 
      print '{}: It\'s a car'.format(by.name) 

    def fixed(self, by): 
     if not self.broken: 
      print 'Car is not broken' 
     else: 
      self.broken = False 
      print by.name, 'fixed the car' 


class Person(object): 
    def __init__(self, name, pro=False): 
     self.name = name 
     self.pro = pro 

    def inspect(self, target): 
     target.inspected(by=self) 

    def fix(self, target): 
     target.fixed(by=self) 

    def inspected(self, by): 
     if self.pro: 
      print '{}: {} is a pro'.format(by.name, self.name) 
     else: 
      print '{}: {} is not a pro'.format(by.name, self.name) 

創建一些對象:

>>> car = Car() 
>>> john = Person('John', pro=True) 
>>> bob = Person('Bob', pro=False) 

現在,用戶可以與他們進行互動²

>>> car.breaks() 
'Car broke' 
>>> john.inspect(car) 
"John: It's a broken car" 
>>> john.fix(car) 
'John fixed the car' 
>>> bob.inspect(john) 
'Bob: John is a pro' 

這裏的問題,如果我們撥打john.fix(bob)那麼我們會得到AttributeError: 'Person' object has no attribute 'fixed'

那麼,聲明/限制哪些方法可以應用於哪些對象的良好和/或'pythonic'方法是什麼?

到目前爲止,我想出了以下思路:

  1. 做一個臃腫基地(抽象)類將必須對所有可能的方法和屬性存根。這裏的缺點是,隨着項目的增長和新方法的增加,它應該單獨更新;所有的孩子班都會有很多不相關的和未使用的東西。另外,並不能真正解決問題。
  2. try...except包裝所有電話。看起來不穩定和'pythonic',並沒有解決問題。
  3. 手動指定方法支持哪些類。隨着項目的增長,不可維護,並且不會嚴格地告知目標類必須具有哪些屬性。
  4. 多重繼承。修正了#3的問題,當使用修復方法創建新的FixAllRobot類時,我們可能會忘記添加目標檢查所需的pro屬性。缺點:class Person(Inspecter, Fixer, ..., TwentyMoreOneFunctionHolder)看起來不值得信賴和可讀。而且我們仍然需要檢查是否可以針對目標使用行動。
  5. 非常像#4,但也繼承了目標端類。缺點:繼承地獄:class Person(Inspecter, CanBeInspected, Fixer, ..., FortyMoreOneFunctionHolder)。優點:看起來像一個解決方案。

注:

  1. 關於檢查和檢查(和其它動作對):對於兩個對象和對象時動作被稱作必須作出一些類別相關的動作。

  2. 現在,相同類的所有對象都存儲在它們的類字典中,其ID爲key。元類跟蹤哪些類創建。用戶通常只能控制一個對象。當用戶發送可能看起來像{"jsonrpc": "2.0", "id": 77, "method": "inspect", "params": {"target": "car", "id": 1}}的RPC請求(實際上是json-rpc)時,將target解析爲目標類,並將id作爲實例標識符。一些可選參數也可能通過params字典傳遞。

旁註:我知道QT信號槽系統,並喜歡它,但我認爲情況並非如此。

Sidenote2:我堅持到Python 2.7

+0

你的問題沒有多大意義。除限制異常外,限制**實際上可以做什麼? Python已經通過引發'AttributeError'來做正確的事情,所以沒有任何問題需要解決。您所需要做的就是爲您的API提供適當的文檔。 – ekhumoro

+0

這不是關於使用限制,而更多的是關於設計其核心的方式,它顯然應該做些什麼來正確添加新功能,比如zope.interface。 – mFoxRU

+0

您給出的「問題」示例具體是使用限制 - 即使用錯誤的參數類型調用「john.fix」。 – ekhumoro

回答

1

我建議用try...except方法去。 EAFP(根據https://docs.python.org/2/glossary.html#term-eafp被認爲是pythonic)「容易要求寬恕而不是許可」。隨着項目的發展,它也很好地擴展。

+0

我的美感告訴我,包裝每一個方法調用嘗試...除了不好看。並在文檔中指出每種新方法也應該這樣做看起來很糟糕。 – mFoxRU

相關問題