인사말, 현재 내 프로그램 중 하나를 리팩토링하고 있으며 흥미로운 문제를 발견했습니다.로컬이 아닌 동등한 데코레이터를 구현하는 방법은 무엇입니까?
나는 오토 마톤에 트랜지션을 가지고있다. 전환에는 항상 시작 상태와 종료 상태가 있습니다. 일부 전환에는 순회시 수행해야하는 특정 작업을 인코딩하는 레이블이 있습니다. 레이블이 없으면 아무런 조치도 취하지 않습니다. 일부 전이에는이 조건을 통과하기 위해 충족되어야하는 조건이 있습니다. 조건이 없으면 기본적으로 NFA에서의 엡실론 전환이며 입력 기호를 사용하지 않고 통과합니다.
나는 다음과 같은 작업이 필요합니다 전환이 레이블
- 확인 전환이 조건이있는 경우 전환에
- 확인 레이블을 추가이 레이블
- 를 얻을 수
- 이 조건을 얻으십시오
- 동등성을 확인하십시오
첫 번째 5 가지 점을 살펴보면, 이것은 기본 전환과 두 개의 데코레이터 인 라벨이 붙은 상태 인 명확한 데코레이터처럼 들립니다. 그러나 두 가지 전환은 시작 상태와 끝 상태가 같고 두 전환의 레이블이 동일하거나 존재하지 않고 두 조건이 동일하거나 존재하지 않으면 두 전환이 동일하게 간주됩니다. . 데코레이터를 사용하면 Labeled ("foo", Conditional ("bar", Transition ("baz", "qux"))와 Conditional ("bar", Labeled ("foo", Transition ("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 정확히 예상 다르게 동작으로 - 거기에는 코드가없는 호소하고 I do not는 MI가이 크기로 혼란 스럽다.
물론 세 번째 옵션은 모든 것을 has_label/has_transition에 묶여있는 단일 전환 클래스로 해머하는 것입니다.
그래서 ... 혼란 스럽습니다. 내가 놓친 게 있니? 어떤 구현이 더 좋아 보이는가? 비슷한 경우를 처리하는 방법, 즉 Decorator가 처리 할 수있는 것처럼 보이지만 그와 같은 비 국부적 인 메서드가 돌아 오는 개체를 처리하는 방법은 무엇입니까?
편집 : ConditionalTransition-class가 추가되었습니다. 기본적으로 데코레이터를 생성하는 순서에 의해 생성 된 순서를 제외한 마이너, 시작과 끝의 전환 검사가 올바른지, LabeledTransition 클래스가 레이블이 올바른지 검사하고 ConditionalTransition이 조건이 올바른지 검사합니다.
나에게 보인다. – hop