2017-10-08 126 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)