2010-05-19 3 views
2

유형 검사에 의존하는 약간의 Python 코드가 있습니다. 수학의 언어로 문제를 풀어 볼 것입니다. 그래서 명확합니다. 나는 서로의 서브 세트에 해당하고 상속 체인을 형성하는 몇 개의 클래스를 가지고있다.Python 유형 검사 및 상속 문제

class Real(object): 
    pass 

class Integer(Real): 
    pass 

class Natural(Integer): 
    pass 

그리고 유형이 포함 된 튜플이 있습니다. 이들 각각은 일부 기능의 도메인에 해당합니다.

t1 = (Real, Real) 
t2 = (Real , Integer) 

나는 모든이 튜플 좌표 경우 지정된 도메인의 하위 클래스가 다른 튜플 (Natural , Natural)을 감안할 때 그런 유형 검사의 어떤 모양을하고 싶습니다. 일부 기능 getcompatibles에 대한 예를 들어 내가 가지고 싶습니다

getcompatibles((Real, Real)) = [ t1 ] 
getcompatibles((Real, Integer)) = [ t1, t2 ] 
getcompatibles((Natural, Natural)) = [ t1, t2 ] 
getcompatibles((Natural, Real)) = [ t1 ] 

내가 가지고 올 수있는 유일한 해결책은 도메인 (T1, T2)마다 통해 실행 __subclasses__의 각 유형의를 통해 실행하는 것입니다 및 주어진 입력에 대해 isinstance이 True인지 확인하십시오.

매우 비효율적인데,이 작업을 수행하는 데 더 많은 Pythonic 방식이 있습니까?

+0

변경됨 is_compatible -> getcompatibles –

답변

4
def compatible_pred(obj_types, fun_signature): 
    if len(obj_types) != len(fun_signature): return False 
    return all(issubclass(of, ft) for of, ft in zip(obj_types, fun_signature)) 

def is_compatible(obj_types, fun_signatures=(t1, t2)): 
    return [t for t in fun_signatures if compatible_pred(obj_types, t)] 

하지 술어 정말, 정말 혼란 무언가에 대한 is_compatible 이름은 다음 무엇을 대신 강력 조건 사운드 iscompatible을 사용할 수 있도록, 왜 그런 getcompatibles로에게 재치있는 이름을 부여하지 나는 compatible_pred으로 이름을 지어야 했습니까?

+0

아름답게 작동합니다. –

+0

@Mark, fixed, thanks. 감사합니다. –

+0

@freyrs, 언제든지 환영합니다. 언제나 도움을 드리겠습니다! –

1

예외 처리를 할 필요가 없을 때 유형을 확인하지 마십시오. 예상을 위반 한 인스턴스를 잡으려면 try/except입니다.

isinstance을 반복적으로 호출하면 "지연 형"(강하게 타이핑되고 덜 순진한 사람들) 언어 인 Python에서 오버 헤드가 발생할 수 있습니다. 그런 디자인 문제에 직면 할 때 내가 묻는 질문은 "이 기능이 원주민 쌍을 다루기를 원하지 않는다면 왜 그들과 통화 했습니까?" 아마도 당신은 is_compatible을 조건으로하는 일종의 조건부 분기를 수행하고 있습니다. 조건부 호출로 변경하는 것이 좋습니다.

is_compatible의 결과를 어떻게 사용하는지 보는 것이 좀 더 집중적 인 대답을 허용합니다.