本文档根据你的学习笔记整理,修正了部分笔误,补充了示例代码,并在最后给出一个综合示例程序。
目标:把零散笔记变成可查阅、可练习、可整合进安全工具的知识地图。
目录
- 学习地图
- 基础语法
- 数据类型
- 可变与不可变
- 切片与访问
- 函数
- 函数式编程
- 面向对象编程
- 推导式
- 作用域
- 闭包
- 参数与解包
- 迭代
- 生成器
- 装饰器
- 上下文管理器
- 正则
- 综合示例程序
- 安全开发思维提示
- 原始记录
1. 学习地图
1 | Python 安全开发基础语法 |
2. 基础语法
2.1 编码规则
- Python 3 默认使用 UTF-8 编码,一般不需要额外声明。
- 文件开头可写:
# -*- coding: utf-8 -*-,但 Python 3 通常可省略。
2.2 注释
1 | # 单行注释 |
- 快捷键:
Ctrl + /可批量注释/取消注释。
2.3 缩进规范
- Python 用缩进表示代码块,推荐 4 个空格。
- 不要混用 Tab 和空格。
1 | if True: |
2.4 变量
- 变量不需要声明类型,直接赋值即可。
- 变量名建议小写,多个单词用下划线:
scan_result。
1 | name = "Alice" |
2.5 多行语句
- 用括号
()、[]、{}可以自然换行。 - 用反斜杠
\也可以换行,但不推荐。
1 | total = (1 + 2 + |
3. 数据类型
| 类型 | 关键字 | 示例 | 特点 |
|---|---|---|---|
| 整数 | int |
42 |
任意大小 |
| 浮点数 | float |
3.14 |
小数 |
| 复数 | complex |
1+2j |
科学计算 |
| 字符串 | str |
"hello" |
不可变 |
| 三引号字符串 | str |
"""多行""" |
保留格式 |
| 布尔 | bool |
True / False |
真/假 |
| 列表 | list |
[1, "a", True] |
可变、有序 |
| 元组 | tuple |
(1, 2, 3) |
不可变、有序 |
| 集合 | set |
{1, 2, 3} |
可变、无序、唯一 |
| 字典 | dict |
{"name": "Alice"} |
键值对 |
| 字节 | bytes |
b"hello" |
二进制 |
| 范围 | range |
range(1, 6) |
惰性序列 |
1 | num = 42 |
4. 可变与不可变
4.1 赋值逻辑
1 | a = {"key": "value"} |
- 列表、字典、集合是可变的,赋值是引用赋值(浅拷贝)。
- 元组、字符串、数字是不可变的,修改会报错。
4.2 深拷贝与浅拷贝
1 | import copy |
- 浅拷贝:
.copy()、list()、dict()。 - 深拷贝:
copy.deepcopy()。
5. 切片与访问
1 | s = "abcdefghijklmn" |
字典访问:
1 | d = {"name": "Alice", "age": 20} |
6. 函数
1 | def add(a, b): |
def定义函数,参数不要求类型。return返回值,没有return则返回None。- 主程序入口:
1 | if __name__ == "__main__": |
match-case(Python 3.10+):
1 | def check_port(port): |
for循环:
1 | for i in range(1, 6): # 左闭右开:1,2,3,4,5 |
7. 函数式编程
7.1 匿名函数 lambda
1 | add = lambda x, y: x + y |
7.2 函数作为参数和返回值
1 | def apply(func, value): |
7.3 高阶函数 map / sorted
1 | nums = [1, 2, 3, 4] |
map(函数, 可迭代对象)返回迭代器,需list()转换。
8. 面向对象编程
8.1 类与对象
- 类:设计蓝图、概念。
- 对象:类的实体化。
1 | class Dog: |
self代表对象本身,定义方法时必须带上。__init__是初始化方法,创建实例时自动调用。
8.2 Python 里所有东西都是对象
1 | def hello(): |
- 函数可以赋值给变量、作为参数、作为返回值。
9. 推导式
1 | nums = [1, 2, 3, 4] |
10. 作用域
- 就近原则:Local → Enclosing → Global → Built-in。
- 修改全局变量用
global,修改外层函数变量用nonlocal。
1 | x = 10 |
1 | def outer(): |
11. 闭包
- 外层函数返回内层函数。
- 内层函数调用外层函数的变量。
- 内层函数记住外层作用域的变量。
1 | def make_counter(): |
安全工具中可用于生成带前缀的日志函数:
1 | def make_logger(prefix): |
12. 参数与解包
12.1 位置参数与关键字参数
1 | def add(a, b): |
12.2 *args 与 **kwargs
1 | def show_args(*args, **kwargs): |
*args:接收任意个位置参数,打包成元组。**kwargs:接收任意个关键字参数,打包成字典。- 一般关键字参数放在最后。
12.3 解包
1 | args_list = [1, 2, 3] |
你笔记里的“冒号形式变成等号形式”,指的就是 **dict 把 {"name": "Bob"} 变成 name="Bob"。
13. 迭代
13.1 for 迭代
1 | web = ["baidu.com", "qq.com"] |
13.2 字典迭代
1 | data = {"name": "Alice", "age": 20} |
- 直接遍历字典,遍历的是 key。
13.3 索引遍历 enumerate
1 | for index, value in enumerate(["a", "b", "c"]): |
13.4 迭代器 iter / next
1 | it = iter([10, 20, 30]) |
14. 生成器
- 特殊迭代器,惰性求值,用到哪读到哪。
- 适合大文件读取、无限序列、大规模爬虫。
14.1 生成器函数 yield
1 | def batch_iter(items, batch_size=3): |
14.2 生成器表达式与 any/all
1 | nums = [1, 2, 3, 4] |
any:或,找到一个就停。all:与,全部满足才 True。
15. 装饰器
- 在不修改原函数代码的情况下,增加功能。
- 本质:
func = decorator(func)。
1 | import time |
@timer等价于slow = timer(slow)。- 可配合闭包、
*args、**kwargs使用。
16. 上下文管理器
with open(...)自动关闭文件。- 自定义上下文管理器可用
__enter__和__exit__,或contextlib。
1 | with open("test.txt", "w", encoding="utf-8") as f: |
17. 正则
- 用于密码强度、提取 IP、解析返回包等。
- 复杂正则可用 AI 辅助,用到再慢慢学。
1 | import re |
18. 综合示例程序
以下程序包含本文档大部分语法点:基础语法、数据类型、切片、函数、lambda、map、sorted、推导式、类、self、闭包、装饰器、生成器、*args/**kwargs、解包、迭代器、enumerate、any/all、match-case、异常处理、上下文管理器、正则。
1 | #!/usr/bin/env python3 |
19. 安全开发思维提示
| 思维 | 说明 |
|---|---|
| 不要信任用户输入 | 所有 input() 都要 .strip().lower() 清洗 |
| 路径要相对脚本目录 | 用 os.path.dirname(os.path.abspath(__file__)) + os.path.join |
| 异常处理 | 文件不存在、网络超时、用户 Ctrl+C 都要捕获 |
| 边扫边写 | 循环中用 "a" 追加,防止中途崩溃丢数据 |
| 正则提取 | 用 re.search / re.findall 解析返回包、提取 IP |
| 函数职责单一 | 一个函数只做一件事,方便复用和调试 |
| 先跑最小版本 | 每写一个函数就跑一次,不要一口气写完 |
| 先抄再改 | 先理解源码,照着敲,再闭卷写,最后改功能 |
文档结束。
附:原始记录
python基础语法
编码规则(默认就行)
注释,井号,多行注释’’’ ‘’’ ,ctrl+/
缩进规范,四个空格
变量不用标记类型
多行语句书写,可以用括号或者斜杠分割
py数据类型
数字:整数,浮点数,复数
字符串:引号包裹
艺术字:三个双引号包裹,可以保留格式
bool
列表list:两个方括号[]包裹的,里面什么都能放
元组tuple:原括弧()包裹
集合set:大括号{}包裹,无序且唯一性
字典dict,索引关键字’’:”,键值对
字节:b”hello”
范围:range
可变和不可变概念
赋值的逻辑
a=内存空间放着一个字典{key:value}
现在令b=a,这时并不会再开一块,而是b指向a的地址,现在导致修改a和b都会影响到这个值
深拷贝和浅拷贝
深的话要.copy()
修改元组会报错,列表可以,所有可变的基本都是浅拷贝(引用赋值)
可以切片访问
s[-1]负索引从后往前走
s[7:13] s[:13] s[0:]切片访问,python会左闭右开
列表里用的最多
lst[-3:-1]也是正序
lst[::2] lst[::-2] 正序倒序隔着输出
访问逻辑 中括号
d字典访问方法
d.get(‘age’,10) get可以让没有的键提前输出
函数
(define)定义
def 函数名(传参): 传参类型没有要求
返回值
主程序入口
if name = “main“
return num % 2 == 0 返回的是bool类型
match-case语句类似switch-case
if not if_case():
for i in range(1,6): 左闭右开
也可放列表for i in [1,2,3,4,5]:
引出概念:函数式编程思想 如JavaScript
匿名函数lambda
add = lambda x,y:x+y
print(add(3,5))
函数可被当成参数也能被当成返回值
map(lambda x:x**2,numbers)
排序sorted(pairs,key=lambda x:x[0])
高阶函数
可以接收函数作为数组
运算符,算数,逻辑,赋值,位运算符,身份运算符is isnot,成员运算符 in,三元运算符
要学开发思维,安全思维,思维模式
进阶上
匿名函数,写一些小函数,冒号,搭配高阶函数,map(函数,可迭代对象(元组等))
面向对象编程
类:设计概念,蓝图
对象是类的实体化
在类里定义属性def_ self self.color
要带上self
创建实例,初始化,属性
python里所有东西都是对象
函数可以赋值给变量,a(),b(),若a=b也改了函数指向,和a=b()不同
函数可以作为参数传递给其他函数
函数可以作为返回值返回 return 函数名
map函数,可以接受一个函数作为参数,高阶函数,使用方法
推导式
简化方式,从已有的可迭代对象进行操作快速生成一个新的可迭代对象
字典推导式,列表推导式
作用域
变量的可见范围,就近原则
当改变变量的值的时候,要加关键字声明是哪个值
闭包
内层函数叫闭包,理解成函数,特点,可以记住外层传的参数
- 外层return 内层函数
- 内层调用外层变量
关键字参数,记住顺序
位置参数和关键字参数
不确定参数个数,关键字参数具有不确定性,使用这个非常灵活
*arges
位置参数,和位置有关系
**kwarges
关键字参数,和位置没关系
比如(name=”value1”, age=25)
一般关键字参数放到最后面
解包:冒号形式变成等号形式
进阶下
迭代
类似于遍历
迭代分两种类型1.for,2.迭代器
for(列表,元组,字典)迭代
比如说一个列表web,想批量加https://协议
那就for i in web:
迭代变量i相当于列表中的每一项元素
i = 'https://' + i
字典迭代
对象可以定义自己的一个方法,比如一个汽车的类,可以定义它的启动方法和停止方法。
字典是一个对象,也有它的一个方法
for key in data.keys()
两个括弧是调用,上面是对keys键进行了遍历
比如改成data.values()对值遍历
或者改成 for key,value in data.items()
(item是直接输出里面的键和值)
若直接遍历字典则遍历的是它的key
索引遍历
inenumerate(列表名) 可以自动打出索引值
如果括号包裹的话,前面也要加括号,要不然会报错(不知道为啥)
迭代器
iter()可以转化为迭代器,能通过next()进行调用,类似于for循环
生成器*
特殊的迭代器,能用到哪读到哪,惰性求值,用完就没了
场景:对于大文件读取,无限序列什么的。大规模爬虫,txt,如果一下全加载会卡,但是用生成器能提高效率
两种形式
生成器函数:
yield关键字(类似能逐步返回,能记录,能状态记忆的return)
函数接受一个值,yield很重要,有一个暂停的状态,有记忆功能,能记录遍历的状态
取得时候print(next(gen)),一个一个取,要用的时候再调用
实际使用:可以一批一批地读取数据,减少负载
1 | if len(batch) == batch_size: |
生成器表达式:(类似于列表推导式)
用的不是很多,两个关键字,any和all就是或和与
常用any,只要判断出一个就不会再往后判断了
装饰器
回忆函数三个特性
如果想便捷的获取某个函数的执行时间
1 | start=time.time() |
有弊端,如果想检测很多个函数,每个都要time.time()然后time-time,很麻烦
注意到函数能返回,函数能传参
定义一个新函数,传一个函数进去,在里面调用它,然后算出时间再返回
但是这个时候有个问题,如果这个函数本身有参数,那就不能传进计时函数中了
这个时候可以升级!使用闭包(闭包,在外部函数能传进来个参数,内部函数也能传,甚至能传关键字参数和位置参数)
这个时候还能升级!使用装饰器!在不影响程序本身代码的情况下,自动把函数传进这个装饰器函数中,然后对自身进行替换
比如用find_time()装饰func(),装饰器就相当于main()中
func=find_time(func)
使用方式:@函数名
也有第三方装饰器可以下载
上下文管理器
with open不需要手动关闭
如果想自定义,可以用装饰器
正则
使用场景,设置密码要求多少位,要求多少种密码等
实战要用到,用正则解析返回包等
用ai写,太复杂了
要用到再慢慢学
261024补
input()返回的是字符串,如数字不能直接相加
变量是贴在对象上的标签,a=3,b=a,a=4。那么a=4,b=3
浮点数存不精确
可变和不可变,比如字符串s=’’,想改只能s+=’!’,已经创建了新的字符串;如列表.append,还是之前那个字符串
字符串的不可变,以及如何增减
算术运算符优先级
逻辑运算and or but也有短路,返回的是操作数本身
复合赋值优先级
