写安全自动化脚本,第一件事是搞清楚数据有哪几种类型Python 把数据分成 8 种,记住它们的区别,你才知道该用哪个装数据、为什么有些数据改不动。


先看全景:8 种类型一张表

类型中文写法(例)装什么能改吗有序吗能重复吗
str字符串"updates needed"一串字符
int整数35没小数点的数
float浮点数5.0带小数点的数
bool布尔True只有真/假两个值
list列表[12, "ok", True]一串有序数据
tuple元组(12, "ok", True)一串改不动的数据
dict字典{1: "East"}键值对✅*键不可重复
set集合{"a", "b"}不重复的一堆值

本课程主要用前 5 个(str / int / float / bool / list),后 3 个(tuple / dict / set)是补充,但安全脚本里都会遇到。 * Python 3.7+ 字典保持插入顺序。

三个判断维度,记住就能选对类型:

  1. 能不能改(可变 vs 不可变)—— 想锁死不让改?用元组。
  2. 有没有顺序 —— 要按位置取?用列表/元组。
  3. 能不能重复 —— 要自动去重?用集合。

5 个基础类型

String 字符串 —— 一串字符,必须加引号

由字母、数字、符号、空格组成的有序字符序列,必须放在引号里。下面都是合法字符串:

"updates needed"
"20%"
"5.0"          # 注意:加了引号就是字符串,不是数字
"35"
""             # 空字符串(引号里啥也没有)

单引号 '' 双引号 "" 都行,但全文统一一种更易读(本课程用双引号)。

print("updates needed")   # 输出: updates needed

安全场景:日志、IP、域名、文件路径、用户名……绝大多数你处理的数据一开始都是字符串。

Integer 整数 —— 没小数点的数,不加引号

-100, -1, 0, 1, 500       # 都是整数
print(5)          # 输出: 5
print(5 + 2)      # 输出: 7,可以直接做运算

注意 "35"(字符串)和 35(整数)是两码事——前者不能做加法。

Float 浮点数 —— 带小数点的数

-2.2, 0.0, 0.34           # 都是浮点
print(1.2 + 2.8)  # 输出: 4.0

一个容易踩的坑——两种除法:

print(1 / 4)      # 输出: 0.25  ← 单斜杠,结果一定是 float
print(1 // 4)     # 输出: 0     ← 双斜杠,向下取整成整数
print(1.0 // 4.0) # 输出: 0.0   ← 向下取整,但保持 float 类型

/ 永远给小数,// 向下取整。算”每页显示几条""平均每天几次告警”这种要整数的场景,用 //

Boolean 布尔 —— 只有 True / False

不加引号。常用来表示”是否""通过没通过""有没有权限”:

print(True)       # 输出: True
print(9 > 10)     # 输出: False,比较运算会返回布尔值

安全脚本里布尔无处不在:is_authenticatedaccess_grantedis_malicious……判断逻辑全靠它。

List 列表 —— 一串有序、可改的数据

方括号 [],逗号分隔,元素可以是任意类型(甚至混着放、嵌套列表):

[12, 36, 54, 1, 7]
["eraab", "arusso", "drosas"]      # 一串用户名
[15, "approved", True, 45.5]       # 混合类型
[]                                  # 空列表
print([12, 36, 54, 1, 7])

列表能改——这是它和元组的关键区别。增删改元素都行,适合装”会变动的一批东西”,比如待处理的 IP 名单。


3 个补充类型

Tuple 元组 —— 像列表,但锁死改不动

圆括号 (),其余和列表一样能混类型:

("wjaffrey", "arutley", "dkot")
(46, 2, 13, 2, 8)
("wjaffrey", 13, True)

和列表唯一的核心差别:元组创建后不能改。 这在安全里正是优点——

为什么安全场景偏爱元组:比如把”允许/拦截的软件标识符”存进元组,就能确保这份名单不会被代码后续意外改动,访问控制列表永远只拦你本来想拦的东西。“改不动”本身就是一种保护。

额外好处:元组比列表更省内存,数据量大时更划算。

Dictionary 字典 —— 键值对映射

花括号 {},每项是 键: 值,逗号分隔。每个键映射到一个值:

{ 1: "East",
  2: "West",
  3: "North",
  4: "South" }

可预测地存取数据时用字典——给个键,立刻拿到值,不用遍历。这正是上一门课讲的 键值对结构在 Python 里的落地;CEF 日志、JSON 解析出来基本都是字典。安全里常用来做映射:端口→服务、用户→权限、IP→地理位置。

Set 集合 —— 自动去重的一堆值

花括号 {},但里面是单个值(不是键值对),无序、且值不能重复:

{"jlanksy", "drosas", "nmason"}    # 一组唯一用户名

集合的杀手锏是自动去重快速判断”在不在里面”。安全场景:从一大堆日志里提取去重后的访问 IP、可疑域名;或快速检查”这个 IP 在不在黑名单里”。


三个配套工具:print() / type() / 注释

光知道类型还不够,还得有工具去它、它、标注它。这三个你会从第一行代码用到最后一行。

最基础的输出函数,调试脚本时全靠它看结果:

print("login success")   # 输出: login success
print(9 < 7)             # 输出: False(先算出比较结果再打印)

type() —— 查一个值到底是什么类型

返回输入数据的类型。当你不确定手上的数据是字符串还是数字时,先 type() 一下——这能省掉一大半”为什么不能做加法""为什么比较结果不对”的困惑:

print(type(51.1))    # 输出: <class 'float'>
print(type(True))    # 输出: <class 'bool'>
print(type("35"))    # 输出: <class 'str'> —— 注意:加了引号就是字符串,不是数字!

安全场景:从日志、API 响应里取出来的数据,默认往往是字符串。拿 "200"(字符串)去和 200(整数)比较会出问题。type() 是你确认”这到底是什么”的第一道检查。

注释 # —— 给代码留说明

# 开启一行注释,Python 会忽略它。注释是写给看的(包括三个月后的你自己),说明代码的意图:

# 打印已批准的用户名
print("approved usernames")

对 vibe-coder 尤其重要:AI 生成的代码常常没注释,或注释只复述代码在干嘛。真正有用的注释写的是为什么这么做(为什么用元组锁死、为什么这里要转类型),而不是”这行在打印”。读 AI 产物时,先补上”为什么”的注释,你才算真看懂了它。


怎么选?三个问题

遇到”该用哪个类型”时,顺着问:

  1. 是单个值还是一堆?

    • 单个 → str / int / float / bool
    • 一堆 → 往下看
  2. 这堆数据要不要改?

    • 不能改(要保护)→ tuple
    • 能改 → 往下看
  3. 要不要去重 / 要不要按键查?

    • 要去重、不在乎顺序 → set
    • 要按键查值 → dict
    • 都不是,就要个有序可改的 → list

一句话总结

8 种类型,本质就在三个维度上排列组合:单值还是集合、可改还是锁死、有序/去重/键值。基础脚本前 5 个够用;但当你要”锁死一份名单”(tuple)、“做映射”(dict)、“自动去重”(set)时,后 3 个能让代码更准、更省事。写安全自动化,选对类型 = 少一半 bug。