2009-09-02 5 views
1

알고리즘을 구현하기위한 클래스를 작성 중입니다. 이 알고리즘은 3 단계의 복잡성을 가지고 있습니다. 그것은이 같은 클래스를 구현하기 위해 나에게 의미가 있습니다 : 나는 calc_algorithm 각 클래스에서 재정의 될 것으로 기대파이썬에서 클래스 앨리어싱

class level0: 
    def calc_algorithm(self): 
     # level 0 algorithm 
     pass 

    # more level0 stuff 

class level1(level0): 
    def calc_algorithm(self): 
     # level 1 algorithm 
     pass 

    # more level1 stuff 

class level2(level1): 
    def calc_algorithm(self): 
     # level 2 algorithm 
     pass 

    # more level2 stuff 

. 특정 명령 줄 옵션에 따라 데이터에서 수준 0, 수준 1 또는 수준 2를 실행하고 싶습니다. 이것은 내가 알고리즘을 호출하는 방법입니다

for offset in itertools.product(*map(xrange, (dim[0] - 1, dim[1] - 1, dim[2] - 1))): 
    algorithm(offset).calc_algorithm  

algorithmlevel0, level1 또는 level2 중 하나입니다.

내가 다른 언어를 할 줄 방법은 다음과 같습니다 내가 할 수 있도록

for offset in itertools.product(*map(xrange, (dim[0] - 1, dim[1] - 1, dim[2] - 1))): 
    if (level == 0):   
     level0(offset).calc_algorithm  
    else: 
     if (level == 1):   
      level1(offset).calc_algorithm  
     else: 
      level2(offset).calc_algorithm  

다른 클래스를 참조하는 클래스의 별명을하는 파이썬 방법이 있나요 :

algorithm = (level == 0) and level0 or (level == 1) and level1 or level2 

을 입력 한 다음 위와 같이 algorithm을 호출 하시겠습니까?


그냥 Aspect 지향적 인 언어가이 같은 클래스 쓸 수있다 Specman을,의 비교에 : 나는 level 구조체 멤버를 설정하면 내가 나머지를 사용할 수 있습니다, 다음

struct algorithm { 
    level: uint; 
    // common stuff for all levels 

    calc_algorithm() is empty; 

    when (level == 0) { 
     calc_algorithm() is only { 
      // level 0 algorithm 
     }; 
    }; 
    when (level == 1) { 
     calc_algorithm() is only { 
      // level 1 algorithm 
     }; 
    }; 
    when (level == 1) { 
     calc_algorithm() is only { 
      // level 1 algorithm 
     }; 
    }; 

}; 

과 수업 중 투명하게

+0

이 정말 클래스를 앨리어싱되지로 레벨을 통과 할 수 - 그것은 "더있어 명령 줄 인수를 기반으로 클래스 선택 "또는"사용자 입력을 기반으로 클래스 선택 "을 선택합니다. –

+0

맞긴하지만 명령 행이나 사용자 입력에서 올 필요는 없습니다. 클래스 사이의 구별은 이전 계산의 결과 일 수 있습니다. –

답변

11

이 라인을 따라 무엇인가 찾고 계십니까?

dispatch = {0: level0, 1: level1, 2:level2} 
dispatch[offset].calc_algorithm 

분명히 키 (및 offset)는 명령 줄에서 올 수 있습니다.

+0

당신의 코드가'level0','level1','level2'은 클래스의 * 인스턴스 *라고 가정합니다. 실제로 인스턴스화하고자하는 클래스입니다. –

+2

그건'dispatch [offset] (..). calc_algorithm' (두 마침표가있는 곳에서 "생성자"인자를 넣거나 아무것도 넣지 않아도됩니다.) – u0b34a0f6ae

4
dispatch = {0:level0, 1:level1, 2:level2} 
algo = dispatch[offset]() # "calling" a class constructs an instance. 
algo.calc_algorithm() 

당신은 반성 더 좋아하는 경우 :

class_name = "level%d" % offset 
klass = globals()[class_name] 
algo = klass() 
algo.calc_algorithm() 
3

열쇠는 점이다 - 다른 언어와는 달리 클래스 '특별한'이고, 당신이 '앨리어스'의 몇 가지 특이한 수단이 있어야 할 위치 그것들은 파이썬에서 완벽하게 정상적인 변수에 의해 참조되는 일급 객체입니다.

그래서 'a'는 'b = a'라고 간단히 'b'로 별칭을 지정할 수 있습니다. 내가 할 수 있도록

는 다른 클래스를 참조하는 클래스의 별명을하는 파이썬 방법이 있나요 :

알고리즘 = (레벨 == 0) 및 LEVEL0 또는 (레벨 == 1) 수준 1 또는 level2

음, 네 말이 맞습니다. 이미 작성한대로 작동합니다.

...

algorithm= level0 if level==0 else level1 if level==1 else level2 

하지만 일련의 접근은 아마도 단순한 이상의 조건문 다음과 같습니다 : 현대 파이썬이 경우/다른 표정을 가지고 있지만 그래서 오늘은 일반적으로 말하고 싶지만 개인적으로

algorithm= (level0, level1, level2)[level] 
2

, 나는 않을 것 3 개의 클래스를 만들지 만 3 개의 다른 계산 방법을 가진 하나의 클래스를 만들고 필요에 따라 공식 계산 방법 (계산 인터페이스)을 dinamically 변경하십시오. 예를 들어 : 당신이 실행하는 동안 dinamically calcFunction을 변경할 필요가없는 경우

class algorithm: 
    def __init__(self, level = 0): 

     self.level = level 
     self.calcFunctions = {0: self.calcLevel0, 1: self.calcLevel1, 2:self.calcLevel2} 
     #initial value for calc function 
     self.setLevel(level) 

    def setLevel(self, newlevel): 
     self.level = newlevel 
     self.calc = self.calcFunctions[level]  

    def calcLevel0(self): 
     """Level 0 calc algorithm""" 
     #... 
     pass 

    def calcLevel1(self): 
     """Level 1 calc algorithm""" 
     #... 
     pass 

    def calcLevel2(self): 
     """Level 2 calc algorithm""" 
     #... 
     pass 


#class in use: 

#level (taken from command line in your case) 
level = 1 

alg = algorithm() 
alg.setLevel(level) 
alg.calc() 

, 당신은 또한 클래스 생성자

+0

이것은 우아한 해결책입니다. 처음에는 if를 제외하고'if' 문을 가진'calc' 함수를 하나 가지고 있다고 생각했습니다. 다른 클래스를 선호하는 이유는 각 레벨마다 다른 레벨에있을 필요가없는 다양한 테이블이 필요하기 때문입니다. 같은 파일에이 모든 것을 넣으면 매우 지저분 해졌습니다. 다른 클래스에 있으면 다른 파일에있을 수도 있으므로 코드를 더 쉽게 관리 할 수 ​​있습니다. –

+0

귀하의 요지를 이해합니다. 어쨌든 필요한 수준에 따라 다른 테이블 로더도 설정할 수 있습니다. –

+0

어떻게 할 수 있습니까? –

관련 문제