4、Python基础速通(二):条件判断、循环语句、函数定义与模块导入
好,咱们接着聊。上一章我们把 Python 的基本数据类型和变量讲透了,这一章要进入真正的「逻辑控制」环节。
说白了,写脚本就是让机器按照你的思路去干活。怎么让它「看情况办事」?怎么让它「重复干活」?怎么把一段逻辑「打包复用」?
这就是今天要啃的三个硬骨头:条件判断、循环语句、函数与模块。
核心知识点速览
- if / elif / else 条件分支
- for 循环与 while 循环
- break、continue 控制循环
- def 定义函数与参数传递
- import 导入模块与包管理
4.1 条件判断:让脚本学会「看脸色」
先问个问题:你写脚本的时候,是不是经常遇到「如果 A 就做 X,否则做 Y」的场景?
比如检查设备连通性:如果 ping 通,就收集配置;如果 ping 不通,就记录告警。这就是条件判断的典型用法。
Python 的条件判断用 if、elif、else 三个关键字搞定。语法很简单,但缩进是命根子——少一个空格都不行。
# 基础语法
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 提供两种循环:for 和 while。
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