Skip to content
📌知识点小结
  • 数据类型说明“这个数据是什么、能做什么操作”。
  • Python 常用基础类型:整数 int、小数 float、字符串 str、布尔 bool(True/False)。
  • 容器类型:列表 list(有序可改)、字典 dict(键值对)、元组 tuple(不可改)、集合 set(不重复)。
  • 不同类型运算规则不同;类型不符会报错,可用 type() 查看、按需转换。
  • 安全脚本常用列表存多个目标/特征,用字典存结构化信息。
✅自测一下

0.26 数据类型:数字、字符串、布尔、列表、字典 ​

第〇篇【零基础预科】免费。变量里能放各种数据,这一篇认识它们的"种类"。

一、为什么要分类型 ​

不同数据能做的事不同:数字能加减,文字能拼接查找,"是/否"用来判断。类型决定了数据的含义和可用操作。

你可能会问:为什么要分类型,不能让电脑自己判断吗? 分类型其实是在避免歧义。123 这个东西,它是数字"一百二十三"、还是字符串"一二三"?如果不区分,你写 "123" + 1 时电脑就懵了——是要把它们拼成 "1231",还是算出 124?分了类型,规则就明确:数字和数字才能加,字符串和字符串才能拼。你后面写脚本时遇到 TypeError,基本都是"类型没对上"——比如从接口拿到的状态码是字符串 "200",你却拿它和数字 200 去比。

二、基础类型 ​

python
age = 20              # int 整数
price = 9.9           # float 小数
name = "eason"        # str 字符串(文本,用引号)
is_admin = True       # bool 布尔,只有 True / False
nothing = None        # None 表示“空/没有值”
类型例子说明
int20、-3整数
float9.9小数
str"hello"、'x'文本,必须引号
boolTrue / False真假

int 和 float 的区别也值得一提。20 是整数,20.0 是浮点数。为什么要分?因为在电脑里它们存的方式不同——整数精确、运算快,浮点数有小数位、会出现 0.1 + 0.2 != 0.3 这种精度问题。安全脚本里你大多数时候用 int 存端口、状态码、计数;float 用得少,知道有这回事、遇到不慌即可。

这里有两个新手必踩的坑。一是字符串必须用引号包起来:name = "eason" 是把文字存进变量;要是忘了引号写成 name = eason,Python 会以为 eason 是另一个变量名,跑去查它的值,查不到就报 NameError。二是布尔值只有 True 和 False,首字母必须大写、不能加引号;写成 true(小写)或 "True"(带引号)都是错的,Python 不认识。

None 值得单独说一句。它不是"0"、不是"空字符串"、不是"False"——它是一个独立的类型,表示"这里什么都没有/还没赋值"。函数没有显式 return 时默认返回 None;接口请求失败时你也可能拿到 None。判断"这个变量是不是还没设值"时,要写 if x is None,而不是 if x == 0。

三、容器类型 ​

python
ports = [22, 80, 443]                 # list 列表:有序、可改
person = {"name": "eason", "age": 20} # dict 字典:键值对
coords = (1, 2)                       # tuple 元组:有序但不可改
uniq = {1, 1, 2, 3}                   # set 集合:自动去重

列表 vs 字典(重点) ​

  • 列表像一排有编号的格子,用下标(从 0 开始)访问:

    python
    ports[0]     # 22
    ports.append(8080)   # 末尾添加
  • 字典用"键"查"值",适合存属性:

    python
    person["name"]   # "eason"

举个安全场景帮你记住区别。你要存一批待扫的端口,顺序无所谓、还会往里加新端口——用列表 [22, 80, 443],因为它就是"一排格子、按编号取、能增能删"。你要存某个漏洞的特征,比如"这个漏洞的 URL 长什么样、利用参数叫什么、成功标志是什么"——这是一组有关联的属性,用字典 {"url": "/admin", "param": "id", "flag": "success"},因为你要靠"键"(url、param)去取对应的值,而不是记它在第几个位置。

你可能会问:元组和列表看着差不多,为什么要分开? 元组用小括号写、一旦创建就不能改(不能 append、不能改某个位置的值)。它的用途是:存一组"固定不变"的数据,比如一个坐标 (x, y)、一条不可改的配置。用元组而非列表,等于在代码里写明"这组数据不该被改",别人读代码时一眼就知道它是常量。新手前期用列表就够,元组知道有这东西、见过能认出来就行。

四、类型查看与转换 ​

python
type(age)          # <class 'int'>
int("10")          # 把字符串 "10" 转成整数 10
str(20)            # 把数字转成 "20"
len(ports)         # 容器长度
  • 类型不匹配会报 TypeError;
  • 字符串转数字失败(如 int("abc"))会报 ValueError。

这两个报错在写脚本时天天见。TypeError 的意思是"你让我做一个这种类型做不到的操作",比如你拿字符串 "abc" 去和数字 5 相加——电脑不知道该把它们拼成 "abc5" 还是算算术。ValueError 则是"你想转,但这串内容根本不像数字",比如 int("12a")——int() 要求你给它一个能当数字读的字符串,给个 12a 它转不出来。

排查这类问题的第一招是 type()。怀疑哪个变量类型不对,就在它后面打印一句 print(type(x)),跑一遍看输出是 <class 'int'> 还是 <class 'str'>,马上就能定位。新手最常见的错就是:从命令行参数、从文件、从接口读进来的数据,默认都是字符串;你以为它是数字,拿它去算,结果报 TypeError。养成"拿进来先看一眼类型"的习惯,能省一半调试时间。

五、安全脚本中的用法 ​

python
targets = ["http://a.com", "http://b.com"]     # 列表:多个目标
vuln_signatures = ["rmi://", "ldap://"]        # 列表:特征
result = {"url": targets[0], "vuln": True}     # 字典:一条结果

看这三行就能明白安全脚本的典型套路:待打的目标用列表装(因为是一堆同类型的东西、要挨个循环),漏洞特征也用列表装(同样是一堆待匹配的字符串),每打完一个目标、要记录结果时用字典——因为一条结果是"哪条 URL、是否存在漏洞、返回了什么"这组有关联的属性,用键去存比记第几个位置清楚得多。你后面写 PoC、写批量探测器,几乎都是这两套容器的排列组合:列表管"一批同类项",字典管"一组关联属性"。

你可能会问:那集合(set)什么时候用? 集合最大的特点是"自动去重、不讲顺序"。你扫了 100 个目标、发现了 200 个端口,但其中很多重复——丢进集合里,一秒钟帮你去重,剩下的就是"这个目标到底开了哪些不同端口"。前期你用列表和字典就够,集合知道有这东西、用到再查。

六、本篇小结 ​

  • 基础类型:int 整数、float 小数、str 文本、bool 真假、None 空。
  • 容器:list 有序可改、dict 键值对、tuple 不可改、set 去重。
  • 列表按下标(从 0),字典按键;用 type() 看类型、int()/str() 转换。
  • 安全里用列表存目标/特征、字典存结果。

记住这套分工,以后读任何 Python 脚本都能先分清"这是一堆东西、还是一条记录"。

下一篇 0.27 讲条件判断,让程序学会"看情况办事"。