我正在編寫一個服務器應用程序,該功能是通過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'方法是什麼?
到目前爲止,我想出了以下思路:
- 做一個臃腫基地(抽象)類將必須對所有可能的方法和屬性存根。這裏的缺點是,隨着項目的增長和新方法的增加,它應該單獨更新;所有的孩子班都會有很多不相關的和未使用的東西。另外,並不能真正解決問題。
- 用
try...except
包裝所有電話。看起來不穩定和'pythonic',並沒有解決問題。 - 手動指定方法支持哪些類。隨着項目的增長,不可維護,並且不會嚴格地告知目標類必須具有哪些屬性。
- 多重繼承。修正了#3的問題,當使用修復方法創建新的
FixAllRobot
類時,我們可能會忘記添加目標檢查所需的pro
屬性。缺點:class Person(Inspecter, Fixer, ..., TwentyMoreOneFunctionHolder)
看起來不值得信賴和可讀。而且我們仍然需要檢查是否可以針對目標使用行動。 - 非常像#4,但也繼承了目標端類。缺點:繼承地獄:
class Person(Inspecter, CanBeInspected, Fixer, ..., FortyMoreOneFunctionHolder)
。優點:看起來像一個解決方案。
注:
關於檢查和檢查(和其它動作對):對於兩個對象和對象時動作被稱作必須作出一些類別相關的動作。
現在,相同類的所有對象都存儲在它們的類字典中,其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
你的問題沒有多大意義。除限制異常外,限制**實際上可以做什麼? Python已經通過引發'AttributeError'來做正確的事情,所以沒有任何問題需要解決。您所需要做的就是爲您的API提供適當的文檔。 – ekhumoro
這不是關於使用限制,而更多的是關於設計其核心的方式,它顯然應該做些什麼來正確添加新功能,比如zope.interface。 – mFoxRU
您給出的「問題」示例具體是使用限制 - 即使用錯誤的參數類型調用「john.fix」。 – ekhumoro