3、Python基础速通:变量与数据类型、字符串操作、列表与字典、条件与循环
好,咱们直接进入正题。Python 基础这部分,说实话,是运维脚本的「地基」。地基没打好,后面写自动化任务、操作云 API 的时候,你会发现自己处处踩坑。我个人习惯是,学 Python 先别急着看高大上的框架,先把变量、字符串、列表、字典和流程控制玩明白。这五个东西,能覆盖你日常 80% 的脚本需求。
3.1 变量与数据类型:别把「盒子」搞混了
变量是什么?说白了,就是一个贴了标签的盒子。你把数据放进去,然后通过标签来拿。Python 是动态类型语言,你不用像 Java 那样声明「这个盒子只能装整数」。但自由归自由,心里得有数。
核心数据类型速览
| 类型 | 例子 | 说明 |
|---|---|---|
| int | age = 30 |
整数,没有大小限制 |
| float | price = 19.99 |
浮点数,注意精度问题 |
| str | name = "ecs-01" |
字符串,用引号包起来 |
| bool | is_running = True |
布尔值,只有 True/False |
| None | result = None |
空值,不是 0 也不是空字符串 |
我在项目中遇到过一个问题:有人用 if result == None 来判断,结果出 bug 了。正确的写法是 if result is None。为什么?因为 == 比较的是值,is 比较的是内存地址。None 在 Python 里是单例,用 is 更安全、更规范。
我的习惯:变量命名用下划线风格,比如 instance_id、cpu_usage。别用拼音,也别用单个字母(循环变量 i 除外)。你想想看,三个月后回来看脚本,a = b + c 谁能看懂?
3.2 字符串操作:运维脚本的「基本功」
字符串操作太常用了。解析日志、拼接命令、格式化输出,哪哪都离不开。Python 的字符串方法多,但常用的就那么几个。
3.2.1 格式化:别再手动拼了
我见过有人用 + 拼接字符串,写出来又长又容易错。比如:
# 不推荐
cmd = "aws ec2 describe-instances --instance-ids " + instance_id + " --region " + region
# 推荐:f-string(Python 3.6+)
cmd = f"aws ec2 describe-instances --instance-ids {instance_id} --region {region}"
f-string 是我现在唯一用的方式。清晰、高效、不容易漏掉空格。你想想看,如果变量多了,用 + 拼简直是灾难。
3.2.2 常用方法:记住这几个就够了
strip():去掉首尾空白。读配置文件时必用。split():按分隔符切分。解析 CSV 或日志行时常用。join():把列表拼成字符串。注意是字符串调 join,不是列表调。startswith() / endswith():判断开头结尾。过滤日志时很好用。
line = " ERROR: Connection timeout "
clean_line = line.strip() # "ERROR: Connection timeout"
parts = clean_line.split(": ") # ["ERROR", "Connection timeout"]
if clean_line.startswith("ERROR"):
print("发现错误日志")
我曾经踩过的坑:用 split() 时没注意参数。默认是按空白字符切分,连续空格会被当成一个分隔符。如果你需要精确按单个空格切分,要传 split(" ")。嗯,这里要注意。
3.3 列表与字典:管理你的数据集合
列表和字典,是 Python 里最常用的两种数据结构。列表管顺序,字典管映射。运维脚本里,列表常用来存 IP 列表、实例 ID 列表;字典常用来存配置、API 返回的 JSON 数据。
3.3.1 列表:有序的「购物车」
列表用方括号 [],可以放任何类型。常用操作:
ips = ["10.0.0.1", "10.0.0.2", "10.0.0.3"]
ips.append("10.0.0.4") # 追加
ips.remove("10.0.0.2") # 删除指定元素
first_ip = ips[0] # 索引从 0 开始
last_ip = ips[-1] # 负索引,从末尾取
我个人习惯用列表推导式来快速生成列表,比如:
# 生成 1 到 10 的平方
squares = [x**2 for x in range(1, 11)]
# 过滤出大于 50 的
big_squares = [x for x in squares if x > 50]
列表推导式写起来很 Pythonic,但别嵌套太多层。超过两层,可读性就下降了。我一般最多嵌套两层。
3.3.2 字典:键值对的「通讯录」
字典用花括号 {},键必须是不可变类型(字符串、数字、元组)。
instance = {
"id": "i-0abcd1234",
"type": "t2.micro",
"state": "running",
"tags": {"Name": "web-server", "Env": "prod"}
}
# 取值
print(instance["id"]) # 键不存在会报 KeyError
print(instance.get("state")) # 键不存在返回 None,更安全
# 遍历
for key, value in instance.items():
print(f"{key}: {value}")
我的建议:从云 API 拿回来的 JSON 数据,直接就是字典嵌套列表的结构。用 .get() 方法取值,配合默认值,可以避免很多 KeyError。比如 instance.get("state", "unknown")。
3.4 条件与循环:控制你的脚本逻辑
条件判断和循环,是脚本的「大脑」。没有它们,脚本就是一条直线跑到底,啥也干不了。
3.4.1 条件判断:if-elif-else
Python 没有 switch-case,用 if-elif-else 替代。注意冒号和缩进。
cpu_usage = 85
if cpu_usage > 90:
print("严重告警,需要扩容")
elif cpu_usage > 70:
print("警告,关注一下")
else:
print("正常")
这里有个小细节:Python 会把 0、空字符串、空列表、None 当成 False。所以你可以直接写:
if not error_log:
print("没有错误日志,跳过")
而不是 if len(error_log) == 0。更简洁,也更 Pythonic。
3.4.2 循环:for 和 while
for 循环用得最多。遍历列表、字典、文件行,都用 for。
# 遍历列表
for ip in ["10.0.0.1", "10.0.0.2"]:
print(f"Pinging {ip}...")
# 遍历字典
config = {"region": "cn-north-1", "zone": "a"}
for key, value in config.items():
print(f"{key} = {value}")
# 带索引遍历
for idx, ip in enumerate(ip_list):
print(f"第 {idx+1} 个 IP: {ip}")
while 循环用得少,一般用在「不知道要循环多少次」的场景,比如等待某个任务完成:
import time
status = "pending"
while status == "pending":
print("任务还在跑,等 5 秒...")
time.sleep(5)
status = check_status() # 假设这个函数返回最新状态
print("任务完成")
我曾经犯过的错:写 while 循环忘了加退出条件,结果脚本跑成了死循环,把服务器 CPU 打满了。嗯,一定要确保循环体内有改变条件的逻辑,或者加一个最大循环次数做保护。
3.4.3 break 和 continue:循环的「刹车」和「跳过」
break:立即跳出整个循环。continue:跳过本次循环,进入下一次。
for ip in ip_list:
if ip == "10.0.0.100":
print("找到目标 IP,停止搜索")
break
if not ping(ip):
print(f"{ip} 不通,跳过")
continue
print(f"{ip} 正常")
这两个关键字很实用。比如你在遍历实例列表时,找到第一个符合条件的就 break,能省不少时间。
3.5 实战小例子:检查云服务器状态
把今天学的串起来,写一个简单的脚本。假设我们有一个实例列表,要检查每个实例的状态:
instances = [
{"id": "i-001", "name": "web-01", "state": "running"},
{"id": "i-002", "name": "db-01", "state": "stopped"},
{"id": "i-003", "name": "cache-01", "state": "running"},
]
for inst in instances:
name = inst.get("name", "unknown")
state = inst.get("state", "unknown")
if state == "running":
print(f"[OK] {name} 运行正常")
elif state == "stopped":
print(f"[WARN] {name} 已停止,请检查")
else:
print(f"[ERROR] {name} 状态异常: {state}")
你看,变量、字符串、列表、字典、条件、循环,全用上了。这就是基础的力量。
总结一下:变量是盒子,字符串是文本,列表管顺序,字典管映射,条件做判断,循环做重复。把这六个东西练熟,你就能写出大部分运维脚本了。下一章我们讲函数和模块,让代码更整洁、更可复用。