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_idcpu_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}")

你看,变量、字符串、列表、字典、条件、循环,全用上了。这就是基础的力量。

总结一下:变量是盒子,字符串是文本,列表管顺序,字典管映射,条件做判断,循环做重复。把这六个东西练熟,你就能写出大部分运维脚本了。下一章我们讲函数和模块,让代码更整洁、更可复用。