2011-09-09 4 views
1

나는 친구가 쓴 최근에이 기능을 좋게 발견 한 몇 가지 코드를 리팩토링있어를 리팩토링 방법 :파이썬 "스위치 문"

def setup_parameters(self, data): 
    '''Parse raw data to determine game settings.''' 
    for line in data.split('\n'): 
     line = line.strip().lower() 
     if line: 
     tokens = line.split() 

     self.L.debug("tokens: " + str(tokens)) 

     key = tokens[0] 
     if key == 'cols': 
      self.width = int(tokens[1]) 
     elif key == 'rows': 
      self.height = int(tokens[1]) 
     elif key == 'player_seed': 
      random.seed(int(tokens[1])) 
     elif key == 'turntime': 
      self.turntime = int(tokens[1]) 
     elif key == 'loadtime': 
      self.loadtime = int(tokens[1]) 
     elif key == 'viewradius2': 
      self.viewradius2 = int(tokens[1]) 
     elif key == 'attackradius2': 
      self.attackradius2 = int(tokens[1]) 
     elif key == 'spawnradius2': 
      self.spawnradius2 = int(tokens[1]) 

당신이 볼 수 있듯이, 여기 switch 문의 불쾌한 종류가있다, 분명히 사전을 요구합니다. 키가 상수이기 때문에 이것을 클래스 사전으로 쓰고 싶지만, 키는 인스턴스의 속성 (즉, 'cols': self.width)에 매핑되기 때문에 컴파일되지 않습니다.

제 질문은 다음과 같은 코드를 리팩토링하는 올바른 방법은 무엇입니까?

+0

중복 질문 : http://stackoverflow.com/questions/60208/replacements-for-switch-statement-in -python – JBernardo

+3

"분명히"? 무엇을 기반으로할까요? –

+1

코드 리팩토링에 노력하고 있음을 확인하기 위해 표준 Python ConfigParser 모듈을 사용하고보기 바란다. – fabrizioM

답변

6

키를 특성의 이름으로 매핑하고 setattr(self, attribute_name, int(tokens[1])을 사용하여 값을 설정하십시오. 예 :

attribute_dict = dict(cols="width", rows="height", turntime="turntime", ...) 
[...] 
value = int(tokens[1]) 
if key == "player_seed": 
    random.seed(value) 
else: 
    setattr(self, attribute_dict[key], value) 
+1

그는 random.seed (int (토큰 [1]))을 호출하므로 작동하지 않는다. 모든 경우에 대해. –

+0

그런 이유로 별도의''if'' 브랜치로 처리됩니다 : –

+0

코드 샘플을 편집하여 넣을 때까지는 거기에 없었습니다. –

1

액세서 및 람다 함수로 키를 사용하여 사전을 구축하여 각 키의 코드를 실행할 수 있습니다.

1

설치 후

actions = dict(cols = lambda tokens: setattr(self, "width", int(tokens[1]), ... 
       player_seed = lambda tokens: random.seed(int(tokens[1])) 
      ) 

와 같은 액션을 가지는 DICT :

actions[key](tokens)