本文档根据你的学习笔记整理,修正了部分笔误,补充了示例代码,并在最后给出一个综合示例程序。
目标:把零散笔记变成可查阅、可练习、可整合进安全工具的知识地图。


目录

  1. 学习地图
  2. 基础语法
  3. 数据类型
  4. 可变与不可变
  5. 切片与访问
  6. 函数
  7. 函数式编程
  8. 面向对象编程
  9. 推导式
  10. 作用域
  11. 闭包
  12. 参数与解包
  13. 迭代
  14. 生成器
  15. 装饰器
  16. 上下文管理器
  17. 正则
  18. 综合示例程序
  19. 安全开发思维提示
  20. 原始记录

1. 学习地图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Python 安全开发基础语法
├── 基础语法
│ ├── 编码规则
│ ├── 注释
│ ├── 缩进
│ ├── 变量
│ └── 多行语句
├── 数据类型
│ ├── 数字、字符串、bool
│ ├── list、tuple、set、dict
│ ├── bytes、range
│ └── 可变 vs 不可变
├── 流程控制
│ ├── if / elif / else
│ ├── for / while
│ ├── match-case
│ └── 推导式
├── 函数
│ ├── def、return
│ ├── 匿名函数 lambda
│ ├── 高阶函数 map / filter / sorted
│ └── 函数式编程
├── 进阶上
│ ├── 面向对象:类、对象、self
│ ├── 一切皆对象
│ ├── 推导式
│ ├── 作用域
│ ├── 闭包
│ └── *args / **kwargs
└── 进阶下
├── 迭代:for、迭代器、enumerate
├── 生成器:yield、生成器表达式
├── 装饰器
├── 上下文管理器
└── 正则

2. 基础语法

2.1 编码规则

  • Python 3 默认使用 UTF-8 编码,一般不需要额外声明。
  • 文件开头可写:# -*- coding: utf-8 -*-,但 Python 3 通常可省略。

2.2 注释

1
2
3
4
5
6
7
8
9
10
# 单行注释

'''
多行注释
可以写很多行
'''

"""
也可以用三个双引号
"""
  • 快捷键:Ctrl + / 可批量注释/取消注释。

2.3 缩进规范

  • Python 用缩进表示代码块,推荐 4 个空格。
  • 不要混用 Tab 和空格。
1
2
if True:
print("缩进正确")

2.4 变量

  • 变量不需要声明类型,直接赋值即可。
  • 变量名建议小写,多个单词用下划线:scan_result。
1
2
3
name = "Alice"
age = 20
is_admin = False

2.5 多行语句

  • 用括号 ()、[]、{} 可以自然换行。
  • 用反斜杠 \ 也可以换行,但不推荐。
1
2
3
4
5
6
7
total = (1 + 2 +
3 + 4)

nums = [
1, 2, 3,
4, 5, 6
]

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
2
3
4
5
6
7
8
9
10
11
12
13
num = 42
pi = 3.14
complex_num = 1 + 2j
text = "hello"
multi = """第一行
第二行"""
flag = True
lst = [1, 2, 3]
tup = (4, 5, 6)
st = {7, 8, 9}
dct = {"name": "Alice", "age": 20}
data = b"bytes"
rng = range(1, 6)

4. 可变与不可变

4.1 赋值逻辑

1
2
3
4
a = {"key": "value"}
b = a # b 和 a 指向同一个字典
b["key"] = "new"
print(a) # {'key': 'new'},a 也被改了
  • 列表、字典、集合是可变的,赋值是引用赋值(浅拷贝)。
  • 元组、字符串、数字是不可变的,修改会报错。

4.2 深拷贝与浅拷贝

1
2
3
4
5
6
7
8
9
import copy

a = [[1, 2], [3, 4]]
b = a.copy() # 浅拷贝:内层还是同一个引用
c = copy.deepcopy(a) # 深拷贝:完全独立

a[0][0] = 99
print(b) # [[99, 2], [3, 4]]
print(c) # [[1, 2], [3, 4]]
  • 浅拷贝:.copy()、list()、dict()。
  • 深拷贝:copy.deepcopy()。

5. 切片与访问

1
2
3
4
5
6
7
8
9
10
11
12
s = "abcdefghijklmn"
print(s[-1]) # n,负索引从后往前
print(s[7:13]) # hijklm,左闭右开
print(s[:13]) # abcdefghijklm
print(s[0:]) # 全部
print(s[::2]) # 每隔一个取
print(s[::-1]) # 倒序

lst = [1, 2, 3, 4, 5]
print(lst[-3:-1]) # [3, 4]
print(lst[::2]) # [1, 3, 5]
print(lst[::-2]) # [5, 3, 1]

字典访问:

1
2
3
d = {"name": "Alice", "age": 20}
print(d["name"]) # Alice
print(d.get("gender", "未知")) # 未知,get 可设默认值

6. 函数

1
2
3
4
5
6
7
8
9
def add(a, b):
return a + b

def is_even(num):
return num % 2 == 0 # 返回 bool

if __name__ == "__main__":
print(add(1, 2))
print(is_even(4))
  • def 定义函数,参数不要求类型。
  • return 返回值,没有 return 则返回 None。
  • 主程序入口:
1
2
if __name__ == "__main__":
main()
  • match-case(Python 3.10+):
1
2
3
4
5
6
7
8
9
10
def check_port(port):
match port:
case 80:
return "HTTP"
case 443:
return "HTTPS"
case 6379:
return "Redis"
case _:
return "未知"
  • for 循环:
1
2
3
4
5
for i in range(1, 6):   # 左闭右开:1,2,3,4,5
print(i)

for i in [1, 2, 3, 4, 5]:
print(i)

7. 函数式编程

7.1 匿名函数 lambda

1
2
add = lambda x, y: x + y
print(add(3, 5)) # 8

7.2 函数作为参数和返回值

1
2
3
4
5
6
7
8
9
10
11
12
def apply(func, value):
return func(value)

print(apply(lambda x: x * 2, 10)) # 20

def make_adder(n):
def adder(x):
return x + n
return adder

add5 = make_adder(5)
print(add5(10)) # 15

7.3 高阶函数 map / sorted

1
2
3
4
5
6
7
nums = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, nums))
print(squares) # [1, 4, 9, 16]

pairs = [("b", 2), ("a", 1)]
sorted_pairs = sorted(pairs, key=lambda x: x[0])
print(sorted_pairs) # [('a', 1), ('b', 2)]
  • map(函数, 可迭代对象) 返回迭代器,需 list() 转换。

8. 面向对象编程

8.1 类与对象

  • 类:设计蓝图、概念。
  • 对象:类的实体化。
1
2
3
4
5
6
7
8
9
10
class Dog:
def __init__(self, name, color):
self.name = name # 属性
self.color = color

def bark(self):
print(f"{self.name} 在叫")

d = Dog("旺财", "黄色")
d.bark() # 旺财 在叫
  • self 代表对象本身,定义方法时必须带上。
  • __init__ 是初始化方法,创建实例时自动调用。

8.2 Python 里所有东西都是对象

1
2
3
4
5
6
7
def hello():
print("hello")

a = hello # a 指向 hello 函数
a() # hello

b = hello() # b 是返回值 None,同时执行了 hello
  • 函数可以赋值给变量、作为参数、作为返回值。

9. 推导式

1
2
3
4
5
6
7
8
9
10
11
12
nums = [1, 2, 3, 4]

# 列表推导式
squares = [x ** 2 for x in nums]
evens = [x for x in nums if x % 2 == 0]

# 字典推导式
dict_comp = {x: x ** 2 for x in nums}

print(squares) # [1, 4, 9, 16]
print(evens) # [2, 4]
print(dict_comp) # {1: 1, 2: 4, 3: 9, 4: 16}

10. 作用域

  • 就近原则:Local → Enclosing → Global → Built-in。
  • 修改全局变量用 global,修改外层函数变量用 nonlocal。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x = 10

def func():
x = 5
print(x) # 5

func()
print(x) # 10

def change():
global x
x = 20

change()
print(x) # 20
1
2
3
4
5
6
7
8
9
def outer():
x = 10
def inner():
nonlocal x
x = 20
inner()
print(x) # 20

outer()

11. 闭包

  • 外层函数返回内层函数。
  • 内层函数调用外层函数的变量。
  • 内层函数记住外层作用域的变量。
1
2
3
4
5
6
7
8
9
10
11
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter

c = make_counter()
print(c()) # 1
print(c()) # 2

安全工具中可用于生成带前缀的日志函数:

1
2
3
4
5
6
7
def make_logger(prefix):
def log(msg):
print(f"[{prefix}] {msg}")
return log

redis_log = make_logger("Redis")
redis_log("开始扫描") # [Redis] 开始扫描

12. 参数与解包

12.1 位置参数与关键字参数

1
2
3
4
5
def add(a, b):
return a + b

add(1, 2) # 位置参数
add(b=2, a=1) # 关键字参数

12.2 *args 与 **kwargs

1
2
3
4
5
def show_args(*args, **kwargs):
print("位置参数:", args)
print("关键字参数:", kwargs)

show_args(1, 2, name="Alice", age=20)
  • *args:接收任意个位置参数,打包成元组。
  • **kwargs:接收任意个关键字参数,打包成字典。
  • 一般关键字参数放在最后。

12.3 解包

1
2
3
4
5
args_list = [1, 2, 3]
kwargs_dict = {"name": "Bob", "age": 25}

show_args(*args_list) # 解包列表为位置参数
show_args(**kwargs_dict) # 解包字典为关键字参数

你笔记里的“冒号形式变成等号形式”,指的就是 **dict 把 {"name": "Bob"} 变成 name="Bob"。


13. 迭代

13.1 for 迭代

1
2
3
4
web = ["baidu.com", "qq.com"]
for i in web:
i = "https://" + i
print(i)

13.2 字典迭代

1
2
3
4
5
6
7
8
9
10
data = {"name": "Alice", "age": 20}

for key in data.keys():
print(key)

for value in data.values():
print(value)

for key, value in data.items():
print(key, value)
  • 直接遍历字典,遍历的是 key。

13.3 索引遍历 enumerate

1
2
for index, value in enumerate(["a", "b", "c"]):
print(index, value)

13.4 迭代器 iter / next

1
2
3
it = iter([10, 20, 30])
print(next(it)) # 10
print(next(it)) # 20

14. 生成器

  • 特殊迭代器,惰性求值,用到哪读到哪。
  • 适合大文件读取、无限序列、大规模爬虫。

14.1 生成器函数 yield

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def batch_iter(items, batch_size=3):
batch = []
for item in items:
batch.append(item)
if len(batch) == batch_size:
yield batch
batch = [] # 清空批次,防止累加
if batch:
yield batch # 输出剩余不足一批的量

for b in batch_iter([1,2,3,4,5,6,7], 3):
print(b)
# [1, 2, 3]
# [4, 5, 6]
# [7]

14.2 生成器表达式与 any/all

1
2
3
nums = [1, 2, 3, 4]
print(any(x > 3 for x in nums)) # True,任意一个满足
print(all(x > 0 for x in nums)) # True,所有都满足
  • any:或,找到一个就停。
  • all:与,全部满足才 True。

15. 装饰器

  • 在不修改原函数代码的情况下,增加功能。
  • 本质:func = decorator(func)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import time

def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"运行时间:{end - start:.2f} 秒")
return result
return wrapper

@timer
def slow():
time.sleep(1)

slow()
  • @timer 等价于 slow = timer(slow)。
  • 可配合闭包、*args、**kwargs 使用。

16. 上下文管理器

  • with open(...) 自动关闭文件。
  • 自定义上下文管理器可用 __enter__ 和 __exit__,或 contextlib。
1
2
3
with open("test.txt", "w", encoding="utf-8") as f:
f.write("hello")
# 离开 with 块自动关闭

17. 正则

  • 用于密码强度、提取 IP、解析返回包等。
  • 复杂正则可用 AI 辅助,用到再慢慢学。
1
2
3
4
5
6
import re

text = "http://192.168.1.1:6379"
match = re.search(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', text)
if match:
print(match.group(0)) # 192.168.1.1

18. 综合示例程序

以下程序包含本文档大部分语法点:基础语法、数据类型、切片、函数、lambda、map、sorted、推导式、类、self、闭包、装饰器、生成器、*args/**kwargs、解包、迭代器、enumerate、any/all、match-case、异常处理、上下文管理器、正则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
综合示例:IP 安全扫描辅助工具
包含基础语法、数据类型、函数、类、装饰器、生成器、正则、上下文管理器等。
"""

import re
import time
import sys
from functools import wraps

# ========== 装饰器:计时 ==========
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"[计时] {func.__name__} 运行时间:{end - start:.4f} 秒")
return result
return wrapper

# ========== 闭包:日志生成器 ==========
def make_logger(prefix):
def log(msg):
print(f"[{prefix}] {msg}")
return log

# ========== 生成器:分批读取 ==========
def batch_iter(items, batch_size=3):
batch = []
for item in items:
batch.append(item)
if len(batch) == batch_size:
yield batch
batch = []
if batch:
yield batch

# ========== 类:IP 扫描器 ==========
class IPScanner:
def __init__(self, name, targets, port=6379):
self.name = name
self.targets = targets
self.port = port
self.results = []
self.log = make_logger(name)

def clean_targets(self):
pattern = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
cleaned = []
for line in self.targets:
match = pattern.search(line)
if match:
cleaned.append(match.group(0))
self.targets = list(dict.fromkeys(cleaned)) # 去重保序
return self.targets

@timer
def scan(self):
self.log(f"开始扫描,共 {len(self.targets)} 个目标")
for i, batch in enumerate(batch_iter(self.targets, 3), 1):
self.log(f"第 {i} 批:{batch}")
for ip in batch:
cmd = f"redis-cli -h {ip} -p {self.port}"
print(f" 执行:{cmd}")
if ip.endswith(".1"):
self.results.append(ip)
self.log(f"扫描结束,有效 {len(self.results)} 个")
return self.results

def save(self, filename):
with open(filename, "w", encoding="utf-8") as f:
f.write("\n".join(self.results))
print(f"[保存] 结果已写入 {filename}")

# ========== 主程序 ==========
@timer
def main():
# 数据类型
num = 42
pi = 3.14
complex_num = 1 + 2j
text = "hello"
multi = """多行
字符串"""
flag = True
lst = [1, 2, 3]
tup = (4, 5, 6)
st = {7, 8, 9}
dct = {"name": "scanner", "port": 6379}
data = b"bytes"
rng = range(1, 6)

# 切片
print(text[-1], text[1:3], lst[::-1])

# 字典 get
print(dct.get("age", 20))

# 函数与 lambda
add = lambda x, y: x + y
print(add(3, 5))

# map / sorted
nums = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, nums))
pairs = [("b", 2), ("a", 1)]
sorted_pairs = sorted(pairs, key=lambda x: x[0])
print(squares, sorted_pairs)

# 推导式
even_squares = [x ** 2 for x in nums if x % 2 == 0]
dict_comp = {x: x ** 2 for x in nums}
print(even_squares, dict_comp)

# 参数与解包
def show_args(*args, **kwargs):
print("位置参数:", args)
print("关键字参数:", kwargs)

show_args(1, 2, name="Alice", age=20)
args_list = [1, 2, 3]
kwargs_dict = {"name": "Bob", "age": 25}
show_args(*args_list, **kwargs_dict)

# 迭代器
it = iter([10, 20, 30])
print(next(it), next(it))

# any / all
print(any([False, True]), all([True, True]))

# match-case
def check_port(port):
match port:
case 80:
return "HTTP"
case 443:
return "HTTPS"
case 6379:
return "Redis"
case _:
return "未知"

print(check_port(6379))

# 异常处理
try:
risky = 1 / 0
except ZeroDivisionError as e:
print("捕获异常:", e)

# 类与对象
targets = ["192.168.1.1:6379", "http://192.168.1.2", "192.168.1.3"]
scanner = IPScanner("RedisScanner", targets)
scanner.clean_targets()
scanner.scan()
scanner.save("result.txt")


if __name__ == "__main__":
main()

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函数,可以接受一个函数作为参数,高阶函数,使用方法

推导式

简化方式,从已有的可迭代对象进行操作快速生成一个新的可迭代对象

字典推导式,列表推导式

作用域

变量的可见范围,就近原则

当改变变量的值的时候,要加关键字声明是哪个值

闭包

内层函数叫闭包,理解成函数,特点,可以记住外层传的参数

  1. 外层return 内层函数
  2. 内层调用外层变量

关键字参数,记住顺序

位置参数和关键字参数

不确定参数个数,关键字参数具有不确定性,使用这个非常灵活

*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
2
3
4
5
6
if len(batch) == batch_size:

yield batch

batch = [] #清空批次,准备下一次(防结果累加)
#注意输出剩余不足一批次地量!

生成器表达式:(类似于列表推导式)

用的不是很多,两个关键字,any和all就是或和与

常用any,只要判断出一个就不会再往后判断了

装饰器

回忆函数三个特性

如果想便捷的获取某个函数的执行时间

1
2
3
4
5
6
7
start=time.time()

time.sleep(1)

stop=time.time()

print(f"运行时间:{stop-start:.2f}秒")

有弊端,如果想检测很多个函数,每个都要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也有短路,返回的是操作数本身

复合赋值优先级

站内搜索

没有找到内容!