4、Python基础速通(下):函数定义与参数、文件读写操作、异常处理机制、模块与包管理
好,咱们接着聊。上一节我们把Python的底子打牢了,这一节要讲的东西,才是真正让你从「写脚本」变成「写工具」的关键。
函数、文件、异常、模块——这四个东西,说白了就是Python的「四肢」。你光有语法这个大脑不行,得学会怎么组织代码、怎么跟外部交互、怎么处理意外、怎么复用别人的轮子。我刚开始写自动化脚本那会儿,就是吃了不懂模块化的亏,一个脚本上千行,改个参数得翻半天……嗯,后来才明白,好的代码是「搭积木」,不是「糊水泥」。
4.1 函数定义与参数:把重复劳动交给机器
函数是什么?说白了就是「把一段逻辑包起来,起个名字,随叫随到」。我个人的习惯是:只要一段代码出现两次以上,我就把它写成函数。别嫌麻烦,这是运维脚本的命根子。
4.1.1 基本定义与调用
Python用def关键字定义函数,简单直接。你想想看,没有函数的世界多可怕——每次都要把同样的逻辑写一遍,改一个地方得改所有地方。
def check_disk_usage(threshold=80):
"""检查磁盘使用率,超过阈值返回告警"""
import psutil
usage = psutil.disk_usage('/').percent
if usage > threshold:
return f"告警:磁盘使用率已达 {usage}%"
return f"正常:当前使用率 {usage}%"
4.1.2 参数类型详解
Python的参数系统很灵活,但也容易让人迷糊。我把它分成四类,你记住就行:
| 参数类型 | 写法示例 | 说明 |
|---|---|---|
| 必选参数 | def func(a, b) |
调用时必须按顺序传入 |
| 默认参数 | def func(a, b=10) |
不传就用默认值,传了就覆盖 |
| 可变参数 | def func(*args) |
接收任意多个参数,打包成元组 |
| 关键字参数 | def func(**kwargs) |
接收任意多个key=value,打包成字典 |
举个例子,我在写日志收集脚本时经常这么用:
def log_collector(server_ip, *ports, **options):
print(f"目标服务器:{server_ip}")
print(f"监控端口:{ports}")
if options.get('timeout'):
print(f"超时设置:{options['timeout']}秒")
# 实际逻辑省略...
# 调用方式很灵活
log_collector('192.168.1.100', 80, 443, 3306, timeout=30)
None,然后在函数内部判断。
4.2 文件读写操作:和操作系统打交道
运维脚本最常干的事是什么?读日志、写配置、处理数据。文件操作就是你的「手」,得用得溜。
4.2.1 打开文件的正确姿势
Python内置的open()函数是基础,但我强烈建议你用with语句。为什么?因为with会自动帮你关闭文件,不用操心资源泄漏的问题。
# 不推荐的方式(容易忘关文件)
f = open('/var/log/syslog', 'r')
content = f.read()
f.close() # 万一这行忘了呢?
# 推荐的方式(自动关闭)
with open('/var/log/syslog', 'r', encoding='utf-8') as f:
content = f.read()
# 出了with块,文件自动关闭
4.2.2 读写模式一览
模式这东西,记不住没关系,记住常用的几个就行:
'r'— 只读模式,文件必须存在'w'— 写入模式,文件存在则覆盖,不存在则创建'a'— 追加模式,在文件末尾添加内容'rb'/'wb'— 二进制模式,处理图片、压缩包等
重点来了:处理文本文件时,一定要指定encoding参数。我遇到过太多次因为编码问题导致的乱码事故了。Linux下默认UTF-8,Windows下可能是GBK,你不指定,脚本换个环境就崩。
4.2.3 实战:逐行读取大文件
运维日志动不动就几个G,你敢用read()一次性读完?内存直接爆炸。正确的做法是逐行读取:
def grep_log(log_path, keyword):
"""在日志文件中搜索关键字,返回匹配行"""
matches = []
with open(log_path, 'r', encoding='utf-8') as f:
for line in f: # 逐行读取,不占内存
if keyword in line:
matches.append(line.strip())
return matches
# 使用示例
result = grep_log('/var/log/nginx/access.log', '500')
print(f"找到 {len(result)} 条500错误")
4.3 异常处理机制:让脚本学会「扛揍」
脚本跑着跑着突然崩了,这种事你肯定遇到过。异常处理就是给你的脚本穿上「防弹衣」——不是不让它出错,而是出错后能优雅地处理,而不是直接崩溃。
4.3.1 try-except 的基本结构
Python的异常处理很直观:你试着干一件事,如果出错了,就按你指定的方式处理。
try:
# 可能会出错的代码
result = 10 / 0
except ZeroDivisionError:
# 捕获特定异常
print("除数不能为0!")
except Exception as e:
# 捕获其他所有异常(但不推荐滥用)
print(f"发生了未知错误:{e}")
else:
# 没有异常时执行
print("计算成功")
finally:
# 不管有没有异常,都会执行
print("清理工作完成")
except:捕获所有异常。你想想看,连键盘中断(Ctrl+C)都被你吞了,想停都停不下来。至少要写成except Exception as e,把错误信息打印出来。
4.3.2 自定义异常与主动抛出
有时候你需要主动告诉调用者:「这里出问题了」。用raise就可以:
class ConfigError(Exception):
"""自定义配置异常"""
pass
def load_config(file_path):
if not os.path.exists(file_path):
raise ConfigError(f"配置文件 {file_path} 不存在")
# 正常加载逻辑...
我曾经写过一个自动化部署脚本,就是因为没有做异常处理,结果某次配置文件格式错了,脚本直接崩溃,导致线上服务中断了10分钟……从那以后,我每条可能出错的代码都加了try-except。
4.4 模块与包管理:站在巨人的肩膀上
Python最强大的地方之一,就是它的生态。你不需要重复造轮子,别人已经写好了各种功能模块,你直接拿来用就行。
4.4.1 import 的几种方式
导入模块,说白了就是告诉Python:「我要用这个工具箱」。方式有几种:
# 方式1:导入整个模块
import os
print(os.getcwd())
# 方式2:导入特定函数(推荐,减少命名冲突)
from os import getcwd, listdir
print(getcwd())
# 方式3:起别名(处理长名字)
import pandas as pd
import numpy as np
# 方式4:导入所有(不推荐,容易覆盖变量)
# from os import * # 慎用!
4.4.2 包的结构与创建
当你的脚本越来越多,就需要用「包」来组织。包其实就是一个包含__init__.py文件的目录:
my_tools/ # 这是一个包
__init__.py # 包初始化文件(可以为空)
network.py # 网络相关函数
disk.py # 磁盘相关函数
log_utils.py # 日志工具函数
然后在其他脚本中就可以这样导入:
from my_tools.network import check_port
from my_tools.disk import get_disk_usage
4.4.3 pip 包管理
安装第三方库,用pip就够了。我个人建议你养成一个好习惯:每个项目都创建虚拟环境,避免包版本冲突。
# 创建虚拟环境
python -m venv myenv
# 激活虚拟环境(Linux/Mac)
source myenv/bin/activate
# 激活虚拟环境(Windows)
myenv\Scripts\activate
# 安装包
pip install requests paramiko
# 导出依赖清单
pip freeze > requirements.txt
# 别人拿到项目后一键安装
pip install -r requirements.txt
核心原则:永远不要在全局环境里装包!我见过太多人因为全局环境混乱,导致不同项目依赖冲突,最后只能重装Python。虚拟环境就是你的「隔离沙箱」,每个项目各玩各的,互不干扰。
小结
这一节的内容,说白了就是让你从「写单行脚本」升级到「写可维护的工具」。函数让代码可复用,文件操作让脚本能读写数据,异常处理让脚本更健壮,模块管理让代码更清晰。
我个人觉得,这四个技能里,最容易被忽视的是异常处理。很多新手觉得「我的脚本不会出错」,但现实是——网络会断、磁盘会满、配置文件会格式错误。给脚本穿上防弹衣,是对自己负责,也是对线上环境负责。
📌 一句话总结:函数是骨架,文件是血肉,异常是铠甲,模块是武器——四者结合,你就能写出真正能上生产环境的自动化脚本。
公众号:蓝海资料掘金营,微信deep3321