每次调用类方法时自动执行Netmiko连接逻辑的最佳实现方式
解决方案
你遇到的是典型的公共逻辑重复问题,完全可以通过类的基础特性把连接逻辑抽离复用,不需要每个方法重复写连接代码,以下是两种可直接落地的实现:
方案1:标准类封装(新手友好,易维护)
把设备参数组装、连接建立、异常捕获全部放到类的初始化逻辑里,实例化类时就完成连接,所有业务方法直接复用已经建立好的连接即可,不需要重复写连接相关代码。
注意:你原来的类方法定义漏了实例方法的第一个固定参数
self,Python类的实例方法必须传入self用来访问实例挂载的公共属性(比如建好的Netmiko连接)。
完整实现代码:
from netmiko import Netmiko from netmiko.exceptions import NetMikoTimeoutException, NetMikoAuthenticationException class DisplayDeviceInfo: def __init__(self, networkdevice, username, password, device_type='cisco_ios'): # 公共配置和连接统一初始化,所有方法复用 self.device_conf = { 'host': networkdevice[1], 'username': username, 'password': password, 'device_type': device_type, } self.net_connect = None self._build_connection() def _build_connection(self): # 私有方法:统一处理连接逻辑和连接异常 try: self.net_connect = Netmiko(**self.device_conf) except (NetMikoTimeoutException, NetMikoAuthenticationException): print('Unable to connect to the device :(') raise ConnectionError("设备连接失败,终止后续操作") def int_status(self): # 业务逻辑只需要写专属命令操作,不用管连接 output = self.net_connect.send_command('show interface status') print(output) def err_disabled(self): output = self.net_connect.send_command('show interfaces status err-disabled') if not output: print('\nThis switch has no ports in an err-disabled state.\n') else: print(output) def close(self): # 操作完成后主动断开连接 if self.net_connect: self.net_connect.disconnect()
调用方式:
if __name__ == "__main__": test_device = ("core_switch", "192.168.1.10") try: # 实例化时自动完成连接 dev = DisplayDeviceInfo(test_device, username="admin", password="your_device_password") # 直接调用业务方法,不用重复传连接参数 dev.int_status() dev.err_disabled() dev.close() except ConnectionError: # 连接失败的统一处理逻辑 pass
方案2:match-case命令分发(代码更精简,适合多命令场景)
你提到的switch case需求,在Python 3.10+版本中可以用原生match/case语法实现命令统一分发,不需要为每个查询都写单独的方法,把命令和对应输出处理逻辑维护在统一映射表中即可,代码冗余度更低:
from netmiko import Netmiko from netmiko.exceptions import NetMikoTimeoutException, NetMikoAuthenticationException class DisplayDeviceInfo: # 统一维护所有支持的命令、对应输出处理逻辑 CMD_HANDLER_MAP = { "int_status": ( "show interface status", lambda output: print(output) ), "err_disabled": ( "show interfaces status err-disabled", lambda output: print('\nThis switch has no ports in an err-disabled state.\n') if not output else print(output) ) } def __init__(self, networkdevice, username, password, device_type='cisco_ios'): self.device_conf = { 'host': networkdevice[1], 'username': username, 'password': password, 'device_type': device_type, } try: self.net_connect = Netmiko(**self.device_conf) except (NetMikoTimeoutException, NetMikoAuthenticationException): print('Unable to connect to the device :(') self.net_connect = None def run(self, cmd_key): if not self.net_connect: return # match case做逻辑分发 match cmd_key: case key if key in self.CMD_HANDLER_MAP: cmd, output_handler = self.CMD_HANDLER_MAP[key] cmd_output = self.net_connect.send_command(cmd) output_handler(cmd_output) case _: raise ValueError(f"不支持的查询类型: {cmd_key}") def close(self): if self.net_connect: self.net_connect.disconnect()
调用方式:
dev = DisplayDeviceInfo(test_device, "admin", "your_device_password") dev.run("int_status") dev.run("err_disabled") dev.close()
如果你的Python版本低于3.10不支持match/case,直接用字典key判断即可实现完全一样的效果,不需要依赖新语法。
两种方案都把连接逻辑收敛到了一处,后续如果要修改连接参数、调整异常处理逻辑,只需要改一次,所有业务方法自动生效。网络设备场景下建议复用同一个长连接,不需要每次执行命令都重新建连,执行效率更高。
内容的提问来源于stack exchange,提问作者Johnny Pastrami
相关产品推荐
相关产品推荐

