問候,目前我正在重構我的一個程序,並且我發現了一個有趣的問題。如何實現具有非本地平等的裝飾器?
我有一個自動機的轉換。轉換總是有一個開始狀態和一個結束狀態。一些轉換有一個標籤,它編碼一個必須在遍歷時執行的Action。沒有標籤意味着沒有行動。有些轉換有一個條件,爲了遍歷這個條件必須滿足條件,如果沒有條件,轉換基本上是一個NFA中的ε-轉換並且將在不消耗輸入符號的情況下被遍歷。
我需要以下操作:
- 檢查如果過渡有一個標籤
- 得到這個標籤
- 添加標籤的過渡
- 檢查如果過渡有一個條件
- 得到這個條件
- 檢查等號
從前五點看,這聽起來像一個清晰的裝飾器,有一個基本過渡和兩個裝飾器:標籤和條件。但是,這種方法存在一個問題:如果兩個轉換的起始狀態和結束狀態相同,兩個轉換的標籤相同(或不存在)並且兩個條件相同(或不存在),則認爲兩個轉換相等。 。使用裝飾器,我可能會有兩個轉換標記(「foo」,條件(「bar」,轉換(「baz」,「qux」)))和條件(「bar」,標記(「foo」,轉換(「baz 」,‘qux’))),這需要一個非本地的平等,也就是裝飾將需要收集所有數據和轉型必須比較該收集的一組類數據:
class Transition(object):
def __init__(self, start, end):
self.start = start
self.end = end
def get_label(self):
return None
def has_label(self):
return False
def collect_decorations(self, decorations):
return decorations
def internal_equality(self, my_decorations, other):
try:
return (self.start == other.start
and self.end == other.end
and my_decorations = other.collect_decorations())
def __eq__(self, other):
return self.internal_equality(self.collect_decorations({}), other)
class Labeled(object):
def __init__(self, label, base):
self.base = base
self.label = label
def has_label(self):
return True
def get_label(self):
return self.label
def collect_decorations(self, decorations):
assert 'label' not in decorations
decorations['label'] = self.label
return self.base.collect_decorations(decorations)
def __getattr__(self, attribute):
return self.base.__getattr(attribute)
是這是一個乾淨的方法?我錯過了什麼嗎?
我主要是困惑,因爲我可以解決這個問題 - 較長的類名 - 使用協作多重繼承:
class Transition(object):
def __init__(self, **kwargs):
# init is pythons MI-madness ;-)
super(Transition, self).__init__(**kwargs)
self.start = kwargs['start']
self.end = kwargs['end']
def get_label(self):
return None
def get_condition(self):
return None
def __eq__(self, other):
try:
return self.start == other.start and self.end == other.end
except AttributeError:
return False
class LabeledTransition(Transition):
def __init__(self, **kwargs):
super(LabeledTransition).__init__(**kwargs)
self.label = kwargs['label']
def get_label(self):
return self.label
def __eq__(self):
super_result = super(LabeledTransition, self).__eq__(other)
try:
return super_result and self.label == other.label
except AttributeError:
return False
class ConditionalTransition(Transition):
def __init__(self, **kwargs):
super(ConditionalTransition, self).__init__(**kwargs)
self.condition = kwargs['condition']
def get_condition(self):
return self.condition
def __eq__(self, other):
super_result = super(ConditionalTransition, self).__eq__(other)
try:
return super_result and self.condition = other.condition
except AttributeError:
return False
# ConditionalTransition about the same, with get_condition
class LabeledConditionalTransition(LabeledTransition, ConditionalTransition):
pass
類LabledConditionalTransition行爲完全如預期 - 且在那裏沒有代碼是有吸引力和我不要在這個大小上讓MI令人困惑。
當然,第三種選擇是將所有內容都打包成一個包含has_label/has_transition的轉換類。
所以......我很困惑。我錯過了什麼嗎?哪個實現看起來更好?你如何處理類似的情況,也就是說,看起來像裝飾者的對象可以處理它們,但是,那麼這種非本地方法會出現嗎?
編輯: 添加了ConditionalTransition類。基本上,這種行爲類似於裝飾器,減去創建裝飾器順序所創建的順序,開始和結束正確的轉換檢查,LabeledTransition類檢查標籤是否正確以及ConditionalTransition檢查條件是否正確。
我看來像你正在嘗試編寫Java代碼在Python。 – hop 2008-09-30 22:43:23