Python |避免重复代码块

Python |避免重复代码块,python,python-3.x,Python,Python 3.x,在控制虚拟机生命周期的类中,我有两个方法。启动、停止、终止、退出等操作。。等 这些方法的代码几乎相同,例如: def stop(self, instances): """ Stop instance or a group of instances :param instances: List of instances :return: """ try: response = self.ec2_client.stop_instance

在控制虚拟机生命周期的类中,我有两个方法。启动、停止、终止、退出等操作。。等

这些方法的代码几乎相同,例如:

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
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
如您所见,除了执行所需操作的API调用(start_实例和stop_实例)之外,这两种方法几乎相同

是否有一种方法可以编写这样的方法或函数并防止代码重复

提前谢谢

顺便说一句,我想到了装饰器、实例函数、闭包——但就是不知道怎么做


以下答案启发我提出以下解决方案:

    @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行代码,它可以工作:)

您可以存储一个stop:{stop\u instances,start:start\u instances}的映射,然后调用一个函数来完成其余的工作。使用
getattr
self.ec2\u客户端
按名称或整个方法获取成员

伪代码:

\uuuu init\uuuu
中:

self.methodmap = {'start': self.ec2_client.start_instances,
                  'stop': self.ec2_client.stop_instances}
然后,例如:

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
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
时传递方法方向


为了增加魔力(小心!),您还可以自动生成
start
stop
等方法,因为它们都遵循相同的模式。

您可以存储一个
stop:{stop_实例,start:start_实例}
的映射,并调用一个函数来完成其余的操作。使用
getattr
self.ec2\u客户端
按名称或整个方法获取成员

伪代码:

\uuuu init\uuuu
中:

self.methodmap = {'start': self.ec2_client.start_instances,
                  'stop': self.ec2_client.stop_instances}
然后,例如:

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
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
时传递方法方向


为了增加魔力(小心!),您还可以自动生成
start
stop
等方法,因为它们都遵循相同的模式。

生成一个函数

@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)

做一个函数

@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)