2017-10-08 173 views
0

我在控制虛擬機生命週期的類中有幾個方法。如啓動運營,停止,終止,退休..等Python |避免重複代碼塊

的代碼,這些方法幾乎是相同的,例如:

def stop(self, instances): 
    """ 
    Stop instance or a group of instances 
    :param instances: List of instances 
    :return: 
    """ 
    try: 
     response = self.ec2_client.stop_instances(InstanceIds=instances, DryRun=False) 
     print(response) 
    except ClientError as e: 
     print(e) 

    return response 

def start(self, instances): 
    """ 
    Start instance or a group of instances 
    :param instances: List of instances 
    :return: 
    """ 
    try: 
     response = self.ec2_client.start_instances(InstanceIds=instances, DryRun=False) 
     print(response) 
    except ClientError as e: 
     print(e) 

    return response 

正如你所看到的,這兩種方法除了API幾乎相同調用以執行所需的操作(start_instances和stop_instance)。

有沒有辦法一般編寫這樣的方法或函數,並防止重複代碼?

在此先感謝。

P.S.我正在考慮裝飾器,實例功能,關閉 - 但只是不知道如何!


回答以下問題,激發了我以下解決方案:

@staticmethod 
def _request_action_method(action, instances): 
    instance_ids = FleetManager._instance_to_str(instances) 

    def _action_method(): 
     try: 
      response = action(InstanceIds=instance_ids, DryRun=False) 
      print(response) 
     except ClientError as e: 
      print(e) 

    return _action_method 

我能與那些幾行替換+50行代碼和它的作品:)

回答

1

您可以儲存地圖的stop: {stop_instances, start: start_instances}和調用一個單一的功能,其餘的。使用getattr可以通過名稱獲得self.ec2_client的成員,或者只是整個方法。

僞代碼:

__init__

self.methodmap = {'start': self.ec2_client.start_instances, 
        'stop': self.ec2_client.stop_instances} 

然後,例如:

def start(self, instances): 
    return self.run('start', instances) 

def run(self, command, instances): 
    method = self.methodmap[command] 
    try: 
    response = method(InstanceIds=instances, DryRun=False) 
    print(response) 
    except ClientError as e: 
    print (e) 
    return response 

取決於你要多少靈活性,你不必定義self.methodmap但也可以在調用self.run時通過方法方向。

對於額外的魔法(注意!),您可以自動生成startstop等方法,因爲它們都遵循相同的模式。

2

做一個功能比方說

@staticmethod 
def _request(method, instances): 
try: 
    response = method(InstanceIds=instances, DryRun=False) 
    print(response) 
except ClientError as e: 
    print(e) 
return response 

,並呼籲他們

def stop(self, instances): 
    self._request(self.ec2_client.stop_instances, instances) 

def start(self, instances): 
    self._request(self.ec2_client.start_instances, instances)