4、Python基础速通(二):条件判断、循环语句、函数定义与模块导入

好,咱们接着聊。上一章我们把 Python 的基本数据类型和变量讲透了,这一章要进入真正的「逻辑控制」环节。

说白了,写脚本就是让机器按照你的思路去干活。怎么让它「看情况办事」?怎么让它「重复干活」?怎么把一段逻辑「打包复用」?

这就是今天要啃的三个硬骨头:条件判断、循环语句、函数与模块。

核心知识点速览

  • if / elif / else 条件分支
  • for 循环与 while 循环
  • break、continue 控制循环
  • def 定义函数与参数传递
  • import 导入模块与包管理
Python 基础速通(二)知识体系 条件判断 if / elif / else 循环语句 for / while 函数定义 def / return 模块导入 import / from 网络运维典型应用场景 批量设备巡检 → 循环遍历 IP 列表 配置备份 → 条件判断失败重试

4.1 条件判断:让脚本学会「看脸色」

先问个问题:你写脚本的时候,是不是经常遇到「如果 A 就做 X,否则做 Y」的场景?

比如检查设备连通性:如果 ping 通,就收集配置;如果 ping 不通,就记录告警。这就是条件判断的典型用法。

Python 的条件判断用 ifelifelse 三个关键字搞定。语法很简单,但缩进是命根子——少一个空格都不行。

# 基础语法
status = "up"

if status == "up":
    print("接口正常,继续巡检")
elif status == "down":
    print("接口异常,触发告警")
else:
    print("未知状态,人工介入")

我的经验: 写条件判断时,我习惯把最可能发生的情况放在最前面。比如设备巡检,90% 的设备都是正常的,那就把 if status == "up" 放第一个。这样代码执行效率更高,逻辑也更清晰。

还有一个坑:Python 里 == 是比较,= 是赋值。我曾经在凌晨三点排查一个脚本 bug,找了半小时才发现是 if status = "up" 少写了一个等号。嗯,这种低级错误,犯过一次就记住了。

4.2 循环语句:让机器替你「重复劳动」

网络运维最烦什么?重复操作。100 台设备,每台都要 ping 一下、登录一下、抓个配置。手动做?不存在的。

循环就是干这个的。Python 提供两种循环:forwhile

4.2.1 for 循环:遍历一切可遍历的东西

for 循环说白了就是「挨个处理」。你给它一个列表,它就一个一个拿出来给你用。

# 遍历 IP 列表
ip_list = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]

for ip in ip_list:
    print(f"正在巡检设备:{ip}")
    # 这里可以放 ping 或 SSH 的代码

配合 range() 函数,还能生成数字序列。比如你要执行 5 次重试:

for i in range(5):
    print(f"第 {i+1} 次重试...")
    # 重试逻辑

避坑指南: 我曾经在遍历列表时直接修改列表元素,结果导致索引错乱。记住:遍历时不要增删列表元素,否则你会怀疑人生。

4.2.2 while 循环:条件满足就一直干

while 循环适合「不知道要循环多少次」的场景。比如等待设备启动完成:

import time

device_ready = False
retry_count = 0

while not device_ready and retry_count < 10:
    print(f"等待设备就绪... 第 {retry_count+1} 次检查")
    # 模拟检查设备状态
    if retry_count >= 5:
        device_ready = True
    retry_count += 1
    time.sleep(2)

print("设备就绪,开始操作")

警告:while 循环一定要有退出条件!否则就是死循环。我见过有人写 while True: 忘了加 break,脚本跑了一整夜,CPU 飙到 100%。

4.2.3 break 和 continue:循环的「刹车」和「跳过」

break 是直接跳出整个循环,continue 是跳过当前这次,继续下一次。

# 找到第一个可用的设备就停止
for ip in ip_list:
    if ping_test(ip):  # 假设 ping_test 返回 True/False
        print(f"找到可用设备:{ip}")
        break  # 找到了,后面的不用看了
    else:
        continue  # 这个不行,继续找下一个

4.3 函数定义:把你的「绝活」打包

写脚本时间长了你会发现,很多代码片段反复出现。比如 SSH 登录、ping 测试、日志记录。每次都复制粘贴?太 low 了。

函数就是把这些逻辑「打包」起来,起个名字,随叫随到。

def ping_test(ip_address, count=4):
    """
    测试设备连通性
    :param ip_address: 设备 IP
    :param count: ping 包数量,默认 4 个
    :return: True 表示可达,False 表示不可达
    """
    import subprocess
    result = subprocess.run(
        ["ping", "-c", str(count), ip_address],
        capture_output=True,
        text=True
    )
    return result.returncode == 0

# 调用函数
if ping_test("192.168.1.1"):
    print("设备可达")
else:
    print("设备不可达")

我的习惯: 每个函数都写 docstring(就是那个三引号注释)。别嫌麻烦,三个月后你回头看自己的代码,docstring 能救你一命。我吃过这个亏——写过一段「精妙绝伦」的函数,半年后完全看不懂了。

参数传递要注意:Python 的参数分位置参数和关键字参数。位置参数按顺序传,关键字参数按名字传。默认参数要放在最后面。

# 位置参数
def backup_config(ip, username, password):
    pass

# 关键字参数
backup_config(ip="192.168.1.1", username="admin", password="cisco")

# 默认参数
def backup_config(ip, username="admin", password="cisco"):
    pass

4.4 模块导入:站在巨人的肩膀上

Python 之所以强大,是因为有海量的第三方库。你不需要自己写 ping 命令的封装,subprocess 模块已经帮你做好了。你不需要自己处理 JSON,json 模块就在那里。

导入模块有三种方式:

导入方式 语法 使用示例 适用场景
导入整个模块 import os os.listdir() 常用模块,避免命名冲突
导入特定函数 from os import listdir listdir() 只用一两个函数,简化代码
导入并起别名 import pandas as pd pd.read_csv() 模块名太长,或避免冲突
# 网络运维常用模块
import os          # 文件和路径操作
import sys         # 系统参数
import json        # JSON 数据处理
import subprocess  # 执行系统命令
import paramiko    # SSH 连接(第三方库)
import re          # 正则表达式
import time        # 时间操作

避坑指南: 导入模块时,标准库放前面,第三方库放后面,中间空一行。这是 PEP8 规范,也是行业惯例。我见过有人把 import 写得乱七八糟,排查依赖关系时简直想骂人。

还有一个细节:如果你自己写了一个 utils.py 文件,里面放了一些通用函数,可以用 from utils import * 导入。但我不建议用 *,因为容易覆盖命名空间。显式导入才是好习惯。

4.5 综合实战:批量设备巡检脚本

把今天学的串起来,写一个简单的批量巡检脚本:

import subprocess
import time

def ping_test(ip):
    """测试单个设备连通性"""
    result = subprocess.run(
        ["ping", "-c", "2", "-W", "3", ip],
        capture_output=True,
        text=True
    )
    return result.returncode == 0

def device_check(ip_list):
    """批量巡检设备"""
    online = []
    offline = []
    
    for ip in ip_list:
        print(f"正在检查 {ip}...", end=" ")
        if ping_test(ip):
            print("在线")
            online.append(ip)
        else:
            print("离线")
            offline.append(ip)
        time.sleep(0.5)  # 避免并发太高
    
    return online, offline

# 主程序
if __name__ == "__main__":
    devices = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]
    online_devices, offline_devices = device_check(devices)
    
    print(f"\n巡检完成!在线设备:{len(online_devices)} 台")
    print(f"离线设备:{len(offline_devices)} 台")
    
    if offline_devices:
        print("离线设备列表:")
        for ip in offline_devices:
            print(f"  - {ip}")

我的建议: 这个脚本虽然简单,但已经包含了条件判断、循环、函数定义和模块导入。你可以把它作为模板,往里面加 SSH 登录、配置抓取、日志记录等功能。我最早做自动化就是从这种小脚本开始的,慢慢积累,最后形成了一套完整的运维工具链。

好了,这一章的内容就到这里。条件判断让你的脚本有了「脑子」,循环让它有了「耐力」,函数和模块让它有了「组织性」。这三样东西掌握好,写网络运维脚本就基本够用了。

记住:代码是写给人看的,顺便让机器执行。所以,写清楚、写规范、写可维护,比写「炫技」的代码重要得多。


公众号:蓝海资料掘金营,微信deep3321