当前位置:首页>python>Python 基础速成(JavaScript 工程师完全指南)

Python 基础速成(JavaScript 工程师完全指南)

  • 2026-03-27 21:33:26
Python 基础速成(JavaScript 工程师完全指南)

这是一份专为前端工程师设计的Python完整教程。通过JavaScript对比学习,让你快速掌握Python的所有核心语法。

随着ai普及,对程序员的要求会更高,全栈是趋势

对自己有比较清楚的认知,我大概率一直为牛马

预计学习时间:3-4小时

前置要求:熟悉JavaScript


目录

  1. 基础语法 - 变量、注释、字符串、条件、循环
  2. 数据类型 - 数字、列表、字典、集合、元组
  3. 函数 - 定义、参数、装饰器、闭包
  4. 面向对象 - 类、继承、魔术方法、属性
  5. 异步编程 - async/await、协程、并发
  6. 模块系统 - 导入、包管理、虚拟环境
  7. 常用库 - HTTP、JSON、文件、日期
  8. 高级特性 - 推导式、生成器、上下文管理器
  9. 实战项目 - 完整的实际应用案例
  10. 常见陷阱 - 避免踩坑

基础语法

1. 变量和常量

核心概念:Python的变量不需要声明类型,赋值即创建。这和JavaScript的let类似,但更简洁。

JavaScript vs Python 对比

// JavaScript - 需要关键字声明const PI = 3.14;        // 常量(不可修改)let count = 0;          // 变量(可修改)var oldStyle = 1;       // 不推荐(作用域问题)// 试图修改常量会报错PI = 3.15;  // ❌ TypeError: Assignment to constant variable
# Python - 直接赋值即可PI = 3.14# 约定:大写表示常量(但实际可修改)count = 0# 变量old_style = 1# Python没有var,都是变量# Python没有真正的常量机制PI = 3.15# ✅ 可以修改,但不建议(靠约定)

详细说明

JavaScript的变量声明

  • const:块级作用域,不可重新赋值(但对象属性可修改)
  • let:块级作用域,可重新赋值
  • var:函数作用域,存在变量提升问题

Python的变量声明

  • 无需关键字,直接赋值
  • 动态类型,可以随时改变类型
  • 遵循"鸭子类型":如果它走起来像鸭子,叫起来像鸭子,那就是鸭子

实际案例:变量类型可变

// JavaScript - 类型可变,但需要重新赋值let value = 42;          // numbervalue = "hello";         // string - 可以,但TypeScript会报错value = [123];       // array - 可以
# Python - 类型完全自由value = 42# intvalue = "hello"# str - 完全没问题value = [123]        # list - 很自然value = {"key""val"}   # dict - 随便切换# 查看类型print(type(value))       # <class 'dict'>

命名规范对比

// JavaScript - 驼峰命名(camelCase)const userName = "张三";let userAge = 25;const MAX_SIZE = 100;  // 常量用大写
# Python - 蛇形命名(snake_case)user_name = "张三"user_age = 25MAX_SIZE = 100# 常量用大写# Python命名规范(PEP 8)# 变量和函数:lowercase_with_underscores# 类名:CapitalizedWords# 常量:UPPERCASE_WITH_UNDERSCORES

多变量赋值(Python特有)

// JavaScript - 解构赋值const [a, b, c] = [123];const {name, age} = {name"张三"age25};// 交换变量需要临时变量let x = 1, y = 2;[x, y] = [y, x];  // ES6+ 支持
# Python - 更简洁的多变量赋值a, b, c = 123# 多变量赋值name, age = "张三"25# 同时赋值# 交换变量(Python特色)x, y = 12x, y = y, x                 # 无需临时变量!# 解包(类似解构)first, *middle, last = [12345]print(first)   # 1print(middle)  # [2, 3, 4]print(last)    # 5

实战案例:配置管理

// JavaScript - 常量配置const config = {API_URL"https://api.example.com",TIMEOUT5000,MAX_RETRIES3};// 不能重新赋值config,但可以修改属性// config = {};  // ❌ 错误config.TIMEOUT = 10000;  // ✅ 可以
# Python - 常量配置(约定)# config.py 文件API_URL = "https://api.example.com"TIMEOUT = 5000MAX_RETRIES = 3# 使用from config import API_URL, TIMEOUT# 虽然可以修改,但不应该这样做# TIMEOUT = 10000  # ⚠️ 违反约定# 如果需要真正的常量,可以使用类classConfig:    API_URL = "https://api.example.com"    TIMEOUT = 5000def__setattr__(self, key, value):raise AttributeError("Constants are immutable")

关键点总结

特性
JavaScript
Python
声明关键字
const
/let/var
无,直接赋值
类型检查
运行时(TypeScript编译时)
运行时
常量机制
const
(真正不可变)
约定(大写命名)
命名风格
camelCase
snake_case
多变量赋值
解构(ES6+)
原生支持

2. 注释

// JavaScript// 单行注释/*  多行注释  多行注释*//** * JSDoc 注释 * @param {string}name */
# Python# 单行注释"""多行注释多行注释"""defgreet(name: str) -> str:"""    函数文档字符串(docstring)    Args:        name: 用户名    Returns:        问候语    """returnf"Hello, {name}"

3. 字符串操作

核心概念:Python的字符串功能非常强大,f-string(格式化字符串)几乎和JavaScript的模板字符串一样好用。

基础字符串对比

// JavaScript - 三种字符串定义方式const single = 'Hello';          // 单引号const double = "World";          // 双引号(推荐)const template = `Hello ${name}`// 模板字符串(ES6+)// 多行字符串const multiLine = `  第一行  第二行  第三行`;
# Python - 也是三种方式single = 'Hello'# 单引号double = "World"# 双引号(推荐)f_string = f"Hello {name}"# f-string(Python 3.6+)# 多行字符串multi_line = """  第一行  第二行  第三行"""# 也可以用三个单引号multi_line2 = '''  这也是多行字符串'''

字符串格式化详解

// JavaScript - 模板字符串const name = "张三";const age = 25;// 方式1:模板字符串(推荐)const msg1 = `我叫${name},今年${age}岁`;// 方式2:字符串拼接(老式)const msg2 = "我叫" + name + ",今年" + age + "岁";// 方式3:表达式const msg3 = `明年我${age + 1}岁`;
# Python - 多种格式化方式name = "张三"age = 25# 方式1:f-string(推荐,Python 3.6+)msg1 = f"我叫{name},今年{age}岁"# 方式2:format方法(Python 2.7+)msg2 = "我叫{},今年{}岁".format(name, age)msg3 = "我叫{name},今年{age}岁".format(name=name, age=age)# 方式3:百分号格式化(老式,不推荐)msg4 = "我叫%s,今年%d岁" % (name, age)# 方式4:字符串拼接msg5 = "我叫" + name + ",今年" + str(age) + "岁"# 注意:需要转换类型# f-string中的表达式msg6 = f"明年我{age + 1}岁"msg7 = f"名字长度:{len(name)}"

字符串方法完整对比

// JavaScript - 字符串方法const text = "  Hello World  ";text.length;                    // 13 - 长度text.toUpperCase();            // "  HELLO WORLD  "text.toLowerCase();            // "  hello world  "text.trim();                   // "Hello World"text.split(" ");               // ["", "", "Hello", "World", "", ""]text.includes("Hello");        // truetext.startsWith("  H");        // truetext.endsWith("d  ");          // truetext.replace("Hello""Hi");   // "  Hi World  "text.substring(27);          // "Hello"text.charAt(2);                // "H"text.indexOf("World");         // 8
# Python - 字符串方法(更丰富)text = "  Hello World  "len(text)                      # 13 - 长度(函数,不是方法)text.upper()                   # "  HELLO WORLD  "text.lower()                   # "  hello world  "text.strip()                   # "Hello World" - 去除两端空格text.lstrip()                  # "Hello World  " - 去除左边空格text.rstrip()                  # "  Hello World" - 去除右边空格text.split()                   # ["Hello", "World"] - 自动处理多个空格text.split(" ")                # ["", "", "Hello", "World", "", ""]"Hello"in text                # True - 成员检查text.startswith("  H")         # Truetext.endswith("d  ")           # Truetext.replace("Hello""Hi")    # "  Hi World  "text[2:7]                      # "Hello" - 切片text[2]                        # "H" - 索引text.find("World")             # 8 - 查找位置(找不到返回-1)text.index("World")            # 8 - 查找位置(找不到抛异常)# Python特有的实用方法text.count("l")                # 3 - 统计字符出现次数text.isdigit()                 # False - 是否全是数字text.isalpha()                 # False - 是否全是字母text.isalnum()                 # False - 是否全是字母或数字"-".join(["2026""03""17"]) # "2026-03-17" - 拼接text.capitalize()              # "  hello world  " - 首字母大写text.title()                   # "  Hello World  " - 每个单词首字母大写

字符串切片(Python特色)

// JavaScript - 使用substring/sliceconst text = "Hello World";text.substring(05);   // "Hello"text.slice(05);       // "Hello"text.slice(-5);         // "World" - 倒数5个字符text.slice(6);          // "World" - 从索引6开始// 没有简单的反转字符串方法text.split('').reverse().join('');  // "dlroW olleH"
# Python - 切片功能超强大text = "Hello World"# 基本切片 [start:end:step]text[0:5]          # "Hello" - 从索引0到5(不含5)text[:5]           # "Hello" - 省略start,从头开始text[6:]           # "World" - 省略end,到结尾text[:]            # "Hello World" - 复制整个字符串# 负索引text[-5:]          # "World" - 倒数5个字符text[:-6]          # "Hello" - 到倒数第6个字符text[-1]           # "d" - 最后一个字符# 步长(step)text[::2]          # "HloWrd" - 每隔一个字符text[::-1]         # "dlroW olleH" - 反转字符串!text[1:8:2]        # "el o" - 从1到8,每隔一个# 实用技巧text[::1]          # 正向复制text[::-1]         # 反转text[1::2]         # 奇数索引的字符text[::2]          # 偶数索引的字符

实战案例:处理用户输入

// JavaScript - 验证和清理用户输入functionvalidateEmail(email{  email = email.trim();  // 去空格if (!email.includes('@')) {returnfalse;  }if (!email.endsWith('.com') && !email.endsWith('.cn')) {returnfalse;  }returntrue;}// 提取文件名const path = "/Users/name/document.txt";const fileName = path.split('/').pop();  // "document.txt"
# Python - 更简洁的字符串处理defvalidate_email(email):    email = email.strip()  # 去空格if'@'notin email:returnFalseifnot (email.endswith('.com'or email.endswith('.cn')):returnFalsereturnTrue# 提取文件名path = "/Users/name/document.txt"file_name = path.split('/')[-1]  # "document.txt"# 或者使用pathlib(更专业)from pathlib import Pathfile_name = Path(path).name  # "document.txt"

实战案例:格式化输出

// JavaScript - 格式化金额functionformatMoney(amount{return${amount.toFixed(2)}`;}console.log(formatMoney(1234.5));  // "¥1234.50"// 格式化日期const date = newDate();const formatted = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2'0')}-${String(date.getDate()).padStart(2'0')}`;
# Python - 格式化金额defformat_money(amount):returnf"¥{amount:.2f}"# .2f 表示保留2位小数print(format_money(1234.5))  # "¥1234.50"# 格式化日期from datetime import datetimedate = datetime.now()formatted = date.strftime("%Y-%m-%d")  # "2026-03-17"# f-string高级格式化price = 1234.5678print(f"{price:.2f}")        # "1234.57" - 保留2位小数print(f"{price:,.2f}")       # "1,234.57" - 千分位分隔print(f"{price:>10.2f}")     # "   1234.57" - 右对齐,宽度10print(f"{price:<10.2f}")     # "1234.57   " - 左对齐print(f"{price:^10.2f}")     # " 1234.57  " - 居中对齐# 百分比ratio = 0.8567print(f"{ratio:.2%}")        # "85.67%" - 百分比格式# 科学计数法big_num = 1234567890print(f"{big_num:e}")        # "1.234568e+09"

字符串的不可变性

// JavaScript - 字符串不可变let str = "Hello";str[0] = "h";  // 无效,但不报错console.log(str);  // 还是 "Hello"// 必须重新赋值str = "hello";
# Python - 字符串也不可变text = "Hello"# text[0] = "h"  # ❌ TypeError: 'str' object does not support item assignment# 必须创建新字符串text = "h" + text[1:]  # "hello"# 或者转换成列表再修改chars = list(text)chars[0] = "h"text = "".join(chars)  # "hello"

关键点总结

特性
JavaScript
Python
模板字符串
\
Hello ${name}``
f"Hello {name}"
多行字符串
反引号
"""
 或 '''
字符串长度
str.lengthlen(str)
包含检查
str.includes()in
 运算符
切片
slice()[start:end:step]
反转
复杂
[::-1]
格式化
模板字符串
f-string(更强大)

4. 条件语句

// JavaScriptif (age >= 18) {console.log("成年");elseif (age >= 12) {console.log("青少年");else {console.log("儿童");}// 三元运算符const status = age >= 18 ? "成年" : "未成年";
# Python(注意缩进!)if age >= 18:    print("成年")elif age >= 12:    print("青少年")else:    print("儿童")# 三元表达式status = "成年"if age >= 18else"未成年"

5. 循环详解

核心概念:Python的for循环更像JavaScript的for...of,而不是传统的for(i=0; i<n; i++)

基本循环对比

// JavaScript - C风格for循环for (let i = 0; i < 5; i++) {console.log(i);  // 0, 1, 2, 3, 4}// for...of(遍历值)const arr = [123];for (const item of arr) {console.log(item);  // 1, 2, 3}// for...in(遍历索引,不推荐用于数组)for (const index in arr) {console.log(index);  // "0", "1", "2" - 注意是字符串}// forEach(函数式)arr.forEach((item, index) => {console.log(index, item);});// while循环let i = 0;while (i < 5) {console.log(i);  i++;}
# Python - 没有C风格for,更像for...of# for + range(生成数字序列)for i in range(5):    print(i)  # 0, 1, 2, 3, 4# for...in(直接遍历元素)arr = [123]for item in arr:    print(item)  # 1, 2, 3# enumerate(带索引,类似forEach)for index, item in enumerate(arr):    print(index, item)  # 0 1, 1 2, 2 3# enumerate指定起始索引for index, item in enumerate(arr, start=1):    print(index, item)  # 1 1, 2 2, 3 3# while循环(和JS一样)i = 0while i < 5:    print(i)    i += 1

range()函数详解

# range(stop) - 从0到stop-1for i in range(5):    print(i)  # 0, 1, 2, 3, 4# range(start, stop) - 从start到stop-1for i in range(25):    print(i)  # 2, 3, 4# range(start, stop, step) - 指定步长for i in range(0102):    print(i)  # 0, 2, 4, 6, 8# 倒序for i in range(50-1):    print(i)  # 5, 4, 3, 2, 1# range是惰性的(不会立即生成所有数字)big_range = range(1000000)  # 不占用太多内存print(list(range(5)))  # 转换成列表:[0, 1, 2, 3, 4]

遍历字典

// JavaScript - 遍历对象const user = {name"张三"age25city"北京"};// 遍历键for (const key in user) {console.log(key);}// 遍历值for (const value ofObject.values(user)) {console.log(value);}// 遍历键值对for (const [key, value] ofObject.entries(user)) {console.log(key, value);}
# Python - 遍历字典user = {"name""张三""age"25"city""北京"}# 遍历键(默认)for key in user:    print(key)# 明确遍历键for key in user.keys():    print(key)# 遍历值for value in user.values():    print(value)# 遍历键值对(推荐)for key, value in user.items():    print(f"{key}{value}")

循环控制语句

// JavaScript - break和continuefor (let i = 0; i < 10; i++) {if (i === 3continue;  // 跳过3if (i === 7break;     // 到7就停止console.log(i);  // 0, 1, 2, 4, 5, 6}
# Python - break、continue和elsefor i in range(10):if i == 3:continue# 跳过3if i == 7:break# 到7就停止    print(i)  # 0, 1, 2, 4, 5, 6# Python特有:for...else(循环正常结束时执行)for i in range(5):if i == 10:  # 永远不会满足breakelse:    print("循环正常结束")  # 会执行# 实战:查找元素deffind_element(arr, target):for item in arr:if item == target:            print(f"找到了: {item}")breakelse:        print("没找到")  # 只有没break时才执行

嵌套循环

// JavaScript - 嵌套循环for (let i = 1; i <= 3; i++) {for (let j = 1; j <= 3; j++) {console.log(`${i} x ${j} = ${i * j}`);  }}// 生成二维数组const matrix = [];for (let i = 0; i < 3; i++) {const row = [];for (let j = 0; j < 3; j++) {    row.push(i * 3 + j);  }  matrix.push(row);}
# Python - 嵌套循环for i in range(14):for j in range(14):        print(f"{i} x {j} = {i * j}")# 生成二维数组(列表推导式更简洁)# 传统方式matrix = []for i in range(3):    row = []for j in range(3):        row.append(i * 3 + j)    matrix.append(row)# 列表推导式(一行搞定)matrix = [[i * 3 + j for j in range(3)] for i in range(3)]# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

实战案例:处理数据

# 案例1:过滤和转换数据users = [    {"name""张三""age"25"active"True},    {"name""李四""age"17"active"False},    {"name""王五""age"30"active"True}]# 找出所有活跃的成年用户active_adults = []for user in users:if user["age"] >= 18and user["active"]:        active_adults.append(user["name"])print(active_adults)  # ['张三', '王五']# 案例2:统计分类scores = [85927895886590]grades = {"A"0"B"0"C"0}for score in scores:if score >= 90:        grades["A"] += 1elif score >= 80:        grades["B"] += 1else:        grades["C"] += 1print(grades)  # {'A': 3, 'B': 3, 'C': 1}# 案例3:二维数组操作matrix = [    [123],    [456],    [789]]# 遍历所有元素for row in matrix:for num in row:        print(num, end=" ")  # 1 2 3 4 5 6 7 8 9    print()  # 换行# 按列遍历(使用zip)for col in zip(*matrix):    print(col)  # (1, 4, 7), (2, 5, 8), (3, 6, 9)

迭代器和可迭代对象

# 理解迭代器numbers = [123]# 获取迭代器iterator = iter(numbers)# 手动迭代print(next(iterator))  # 1print(next(iterator))  # 2print(next(iterator))  # 3# print(next(iterator))  # StopIteration异常# for循环的本质就是使用迭代器# 以下代码等价:for num in numbers:    print(num)# 等价于:iterator = iter(numbers)whileTrue:try:        num = next(iterator)        print(num)except StopIteration:break

zip()和enumerate()实用技巧

# zip - 并行遍历多个序列names = ["张三""李四""王五"]ages = [253028]cities = ["北京""上海""广州"]for name, age, city in zip(names, ages, cities):    print(f"{name}{age}岁, 来自{city}")# 转换成字典user_dict = dict(zip(names, ages))# {'张三': 25, '李四': 30, '王五': 28}# enumerate - 带索引遍历tasks = ["写代码""测试""部署"]for index, task in enumerate(tasks, start=1):    print(f"{index}{task}")# 1. 写代码# 2. 测试# 3. 部署# reversed - 反向遍历for num in reversed(range(5)):    print(num)  # 4, 3, 2, 1, 0# sorted - 排序后遍历numbers = [31415]for num in sorted(numbers):    print(num)  # 1, 1, 3, 4, 5

性能对比:循环 vs 推导式

import time# 方式1:传统循环start = time.time()squares1 = []for i in range(1000000):    squares1.append(i ** 2)print(f"循环耗时: {time.time() - start:.3f}秒")# 方式2:列表推导式(更快)start = time.time()squares2 = [i ** 2for i in range(1000000)]print(f"推导式耗时: {time.time() - start:.3f}秒")# 方式3:生成器(最省内存)start = time.time()squares3 = (i ** 2for i in range(1000000))# 只创建生成器,不计算值print(f"生成器耗时: {time.time() - start:.6f}秒")

关键点总结

特性
JavaScript
Python
基本for循环
for(let i=0; i<n; i++)for i in range(n)
遍历数组
for...offor item in list
带索引遍历
forEach((item, i))enumerate()
跳过
continuecontinue
终止
breakbreak
特殊else
for...else
(没break时执行)
并行遍历
手动实现
zip()

数据类型

1. 数字

// JavaScriptconst integer = 42;const float = 3.14;const hex = 0xFF;const binary = 0b1010;
# Pythoninteger = 42float_num = 3.14hex_num = 0xFFbinary = 0b1010# Python 特有:大整数支持big_number = 99999999999999999999999999999

2. 布尔值

// JavaScriptconst isTrue = true;const isFalse = false;// 假值:false, 0, "", null, undefined, NaNif (!value) {console.log("假值");}
# Pythonis_true = True# 注意:首字母大写!is_false = False# 假值:False, 0, "", None, [], {}ifnot value:    print("假值")

3. 数组/列表

// JavaScriptconst arr = [12345];// 常用方法arr.push(6);           // 添加元素arr.pop();             // 删除最后一个arr.shift();           // 删除第一个arr.unshift(0);        // 开头添加arr.slice(13);       // 切片arr.map(x => x * 2);   // 映射arr.filter(x => x > 2); // 过滤arr.reduce((a, b) => a + b); // 归约
# Pythonarr = [12345]# 常用方法arr.append(6)          # 添加元素arr.pop()              # 删除最后一个arr.pop(0)             # 删除第一个arr.insert(00)       # 指定位置插入arr[1:3]               # 切片[x * 2for x in arr]   # 列表推导式(映射)[x for x in arr if x > 2# 列表推导式(过滤)sum(arr)               # 求和# 列表推导式(Python 特色)squares = [x**2for x in range(10)]  # [0, 1, 4, 9, 16, ...]evens = [x for x in range(10if x % 2 == 0]  # [0, 2, 4, 6, 8]

4. 对象/字典

// JavaScriptconst user = {name"张三",age25,skills: ["React""Vue"]};// 访问user.name;           // "张三"user["age"];         // 25// 方法Object.keys(user);   // ["name", "age", "skills"]Object.values(user); // ["张三", 25, [...]]
# Pythonuser = {"name""张三","age"25,"skills": ["React""Vue"]}# 访问user["name"]         # "张三"user.get("age")      # 25(推荐,不存在返回 None)# 方法user.keys()          # dict_keys(['name', 'age', 'skills'])user.values()        # dict_values([...])user.items()         # dict_items([('name', '张三'), ...])# 字典推导式squares = {x: x**2for x in range(5)}  # {0: 0, 1: 1, 2: 4, ...}

5. Set(集合)

// JavaScriptconstset = new Set([1, 2, 2, 3]);  // Set {123}set.add(4);set.has(2);  // trueset.delete(1);
# Pythonmy_set = {1223}  # {1, 2, 3}my_set.add(4)2in my_set  # Truemy_set.remove(1)# 集合操作a = {123}b = {345}a | b  # 并集 {1, 2, 3, 4, 5}a & b  # 交集 {3}a - b  # 差集 {1, 2}

6. None vs null/undefined

// JavaScriptlet value = null;       // 空值let value2 = undefined// 未定义
# Pythonvalue = None# 唯一的空值(类似 null)# 检查if value isNone:    print("空值")if value:  # None 是假值    print("有值")

函数

1. 基本定义

// JavaScriptfunctionadd(a, b{return a + b;}// 箭头函数const add = (a, b) => a + b;// 默认参数functiongreet(name = "Guest"{return`Hello, ${name}`;}
# Pythondefadd(a, b):return a + b# 默认参数defgreet(name="Guest"):returnf"Hello, {name}"# Lambda(类似箭头函数)add = lambda a, b: a + b

2. 参数类型

// JavaScriptfunctionprocess(required, optional = "default", ...rest{console.log(required, optional, rest);}process(12345);  // 1 2 [3, 4, 5]
# Pythondefprocess(required, optional="default", *args, **kwargs):    print(required, optional, args, kwargs)process(1234, key="value")  # 1 2 (3, 4) {'key': 'value'}# *args: 可变位置参数(元组)# **kwargs: 可变关键字参数(字典)

3. 类型提示(Type Hints)

// JavaScript (TypeScript)functionadd(a: number, b: number): number{return a + b;}
# Pythondefadd(a: int, b: int) -> int:return a + b# 复杂类型from typing import List, Dict, Optionaldefprocess_users(    users: List[Dict[str, str]]) -> Optional[str]:return users[0]["name"if users elseNone

面向对象

1. 类定义

// JavaScriptclassUser{constructor(name, age) {this.name = name;this.age = age;  }  greet() {return`Hello, I'm ${this.name}`;  }static createGuest() {returnnew User("Guest"0);  }}const user = new User("张三"25);
# PythonclassUser:def__init__(self, name, age):        self.name = name        self.age = agedefgreet(self):returnf"Hello, I'm {self.name}"    @staticmethoddefcreate_guest():return User("Guest"0)user = User("张三"25)

2. 继承

// JavaScriptclassAdminextendsUser{constructor(name, age, role) {super(name, age);this.role = role;  }  manageUsers() {return"Managing users...";  }}
# PythonclassAdmin(User):def__init__(self, name, age, role):        super().__init__(name, age)        self.role = roledefmanage_users(self):return"Managing users..."

3. 私有属性

// JavaScriptclassUser{  #password;  // 私有字段constructor(password) {this.#password = password;  }}
# PythonclassUser:def__init__(self, password):        self.__password = password  # 双下划线表示私有        self._internal = "internal"# 单下划线表示内部使用(约定)

异步编程

1. Promise vs asyncio

// JavaScriptfunctionfetchData({returnnewPromise((resolve, reject) => {    setTimeout(() => {      resolve("Data");    }, 1000);  });}fetchData()  .then(data =>console.log(data))  .catch(err =>console.error(err));
# Pythonimport asyncioasyncdeffetch_data():await asyncio.sleep(1)return"Data"# 运行asyncio.run(fetch_data())

2. async/await(完全一样!)

// JavaScriptasyncfunctiongetData({try {const data1 = await fetch('/api/data1');const data2 = await fetch('/api/data2');return [data1, data2];  } catch (error) {console.error(error);  }}
# Pythonasyncdefget_data():try:        data1 = await client.get('/api/data1')        data2 = await client.get('/api/data2')return [data1, data2]except Exception as error:        print(error)

3. 并发执行

// JavaScriptasyncfunctiongetAll({const [data1, data2] = awaitPromise.all([    fetch('/api/data1'),    fetch('/api/data2')  ]);}
# Pythonasyncdefget_all():    data1, data2 = await asyncio.gather(        client.get('/api/data1'),        client.get('/api/data2')    )

模块系统

1. 导入导出

// JavaScript// exportexportconst PI = 3.14;exportfunctionadd(a, breturn a + b; }exportdefaultclassUser{}// importimport User, { PI, add } from'./user';import * as Utils from'./utils';
# Python# 文件:user.pyPI = 3.14defadd(a, b):return a + bclassUser:pass# 文件:main.pyfrom user import PI, add, Userimport user  # 导入整个模块from user import *  # 导入所有(不推荐)

2. 包管理

# JavaScriptnpm install axiosnpm install --save-dev jest# Pythonpip install requestspip install pytest

3. 模块路径详解

核心概念:Python用点号表示模块路径,对应文件系统的目录结构。

文件结构 → 模块路径转换

项目目录/├── app/│   ├── __init__.py          ← 标记为Python包│   ├── routers/│   │   ├── __init__.py│   │   ├── user_router.py│   │   └── order_router.py│   └── services/│       ├── __init__.py│       └── user_service.py
# 导入语法 → 文件路径对应关系from app.routers.user_router import router#    └─┬┘ └──┬──┘ └────┬─────┘#    目录  目录      文件名# 对应文件:app/routers/user_router.pyfrom app.services.user_service import UserService# 对应文件:app/services/user_service.py

__init__.py 的作用

# __init__.py 是包的标识文件# 1. 标记目录为Python包app/├── __init__.py    ← 有这个文件,app才是包└── module.py# 2. 简化导入(可选)# app/routers/__init__.pyfrom .user_router import router as user_routerfrom .order_router import router as order_router# 现在可以这样导入from app.routers import user_router, order_router# 而不是# from app.routers.user_router import router# from app.routers.order_router import router

4. 导入模块的四种方式

// JavaScript// 方式1:导入具体内容(推荐)import { Router, middleware } from'./express';// 方式2:导入默认导出import express from'express';// 方式3:导入整个模块import * as Express from'express';// 方式4:别名导入import { Router as ExpressRouter } from'./express';
# Python# 方式1:导入具体内容(推荐)from fastapi import APIRouter, Depends# 方式2:导入整个模块import fastapirouter = fastapi.APIRouter()# 方式3:导入所有(不推荐)from fastapi import *# 方式4:别名导入from fastapi import APIRouter as Routerfrom datetime import datetime as dt# 方式5:相对导入(包内使用)from .user_router import router      # 当前目录from ..services import UserService   # 上级目录from ...utils import helper          # 上上级目录

5. 实战案例:理解项目导入

# === 案例1:main.py 中的导入 ===# 文件:app/main.py(主应用)# 从项目模块导入from app.routers import user_router, order_router#    └────┬─────┘        └─────┬──────┘#      包路径           模块名(文件名)# 等价于导入了两个文件:# - app/routers/user_router.py# - app/routers/order_router.py# 使用app.include_router(user_router.router)  # 访问模块的router属性app.include_router(order_router.router)   # 访问模块的router属性app.include_router(order_router.public_router)  # 访问另一个router# === 案例2:理解FastAPI路由注册 ===# 文件:app/routers/user_router.pyfrom fastapi import APIRouterrouter = APIRouter(    prefix="/users",           # 路径前缀    tags=["用户管理"]          # API文档标签)@router.get("/list")          # 定义接口方法asyncdefget_user_list():return {"data": []}# 在 main.py 中注册from app.routers import user_routerapp.include_router(user_router.router)# 最终接口路径 = prefix + 方法路径# = /users + /list# = /users/list

6. 模块导入的可见性规则

# === my_router.py 文件 ==="""路由模块示例"""# ✅ 公开API(推荐导入)router = APIRouter()logger = get_logger()PUBLIC_CONSTANT = 100defpublic_function():"""这是公开函数"""passclassPublicService:"""这是公开类"""pass# ⚠️ 内部使用(不建议导入)_internal_config = {"key""value"}def_internal_helper():"""内部辅助函数,不要在外部使用"""pass# ❌ 私有(不应该导入)__private_data = "secret"def__private_method():"""私有方法"""pass# 📋 明确声明公开API(推荐)__all__ = ['router','logger','PUBLIC_CONSTANT','public_function','PublicService']# === 在其他文件中使用 ===# ✅ 推荐:只导入公开APIfrom my_router import router, PUBLIC_CONSTANT# ✅ 可以:导入整个模块import my_routermy_router.routermy_router.public_function()# ⚠️ 技术上可行,但不建议from my_router import _internal_helper  # 违反约定# ✅ 遵循__all__from my_router import *  # 只导入__all__中声明的内容

7. 实战技巧:组织导入

# === 推荐的导入顺序(PEP 8规范) ===# 1. 标准库导入import osimport sysfrom datetime import datetimefrom typing import List, Dict, Optional# 2. 第三方库导入from fastapi import APIRouter, Dependsimport requestsfrom sqlalchemy import Column, String# 3. 本地模块导入from app.routers import user_routerfrom app.services.user_service import UserServicefrom app.utils.logger import get_logger# 每组之间空一行

8. package.json vs requirements.txt

// JavaScript: package.json{"name""my-project","version""1.0.0","dependencies": {"axios""^1.0.0",      // ^ 表示兼容版本"express""~4.18.0"// ~ 表示补丁版本  },"devDependencies": {"jest""^29.0.0"  }}
# Python: requirements.txt(更简单)# 生产依赖requests==2.32.5# == 表示精确版本fastapi>=0.115.0# >= 表示最小版本sqlalchemy~=2.0.0# ~= 表示兼容版本# 开发依赖(通常单独一个文件)# requirements-dev.txtpytest>=7.0.0black==23.0.0

9. 实战案例:多级导入

# === 项目结构 ===my_project/├── app/│   ├── __init__.py│   ├── main.py│   ├── routers/│   │   ├── __init__.py│   │   └── api_router.py│   └── services/│       ├── __init__.py│       └── user_service.py└── utils/    ├── __init__.py    └── helper.py# === app/routers/api_router.py ===from fastapi import APIRouterfrom ..services.user_service import UserService  # 相对导入(上级目录)from ...utils.helper import format_date          # 上上级目录router = APIRouter()user_service = UserService()@router.get("/users")defget_users():    users = user_service.get_all()return {"data": users}# === app/main.py ===from fastapi import FastAPIfrom .routers.api_router import router  # 相对导入(当前包内)app = FastAPI()app.include_router(router)

关键点总结

特性
JavaScript
Python
导出方式
显式export
隐式(顶层定义)
私有约定
不export
下划线前缀
路径语法./path/filepath.module
批量导入import *from module import *
明确API
export列表
__all__
列表
包标识package.json__init__.py

常用库

1. HTTP 请求

// JavaScriptconst axios = require('axios');const response = await axios.get('https://api.example.com/data');const data = response.data;
# Pythonimport requestsresponse = requests.get('https://api.example.com/data')data = response.json()# 异步版本import httpxasyncdeffetch():asyncwith httpx.AsyncClient() as client:        response = await client.get('https://api.example.com/data')return response.json()

2. JSON 处理

// JavaScriptconst obj = { name"张三" };const json = JSON.stringify(obj);const parsed = JSON.parse(json);
# Pythonimport jsonobj = {"name""张三"}json_str = json.dumps(obj)parsed = json.loads(json_str)

3. 日期时间

// JavaScriptconst now = newDate();const timestamp = Date.now();const formatted = now.toISOString();
# Pythonfrom datetime import datetimenow = datetime.now()timestamp = datetime.timestamp(now)formatted = now.isoformat()# 日期计算from datetime import timedeltatomorrow = now + timedelta(days=1)

4. 文件操作

// JavaScript (Node.js)const fs = require('fs');// 读文件const content = fs.readFileSync('file.txt''utf8');// 写文件fs.writeFileSync('file.txt''Hello');
# Python# 读文件with open('file.txt''r', encoding='utf-8'as f:    content = f.read()# 写文件with open('file.txt''w', encoding='utf-8'as f:    f.write('Hello')# with 语句自动关闭文件(类似 try-finally)

重要差异

1. 缩进(重要!)

# Python 用缩进表示代码块(没有大括号)ifTrue:    print("缩进4个空格")ifTrue:        print("缩进8个空格")# ❌ 错误:缩进不一致ifTrue:  print("2个空格")    print("4个空格")  # 报错!

2. 命名规范

// JavaScriptconst userName = "张三";        // 驼峰命名functiongetUserName({}       // 驼峰命名classUserManager{}            // 大驼峰
# Pythonuser_name = "张三"# 下划线命名defget_user_name():# 下划线命名passclassUserManager:# 大驼峰pass# 常量MAX_SIZE = 100# 全大写

3. 真值判断

// JavaScriptif (value) {}  // 空字符串、0、null、undefined 都是假// Pythonif value:      // None、0、""、[]、{}、False 都是假

4. 比较运算符

// JavaScripta === b   // 严格相等a == b    // 宽松相等(类型转换)
# Pythona == b    # 相等(值比较)is b    # 同一对象(引用比较)# 例子a = [12]b = [12]a == b    # True(值相同)is b    # False(不是同一对象)

实战练习

练习 1:实现 Array.map

// JavaScript[123].map(x => x * 2)  // [2, 4, 6]
# Python 方案1:列表推导式(推荐)[x * 2for x in [123]]# 方案2:map + lambdalist(map(lambda x: x * 2, [123]))# 方案3:自己实现defmy_map(func, arr):    result = []for item in arr:        result.append(func(item))return resultmy_map(lambda x: x * 2, [123])

练习 2:实现防抖函数

// JavaScriptfunctiondebounce(func, delay{let timer;returnfunction(...args{    clearTimeout(timer);    timer = setTimeout(() => func(...args), delay);  };}
# Pythonimport timefrom threading import Timerdefdebounce(func, delay):    timer = Nonedefwrapper(*args, **kwargs):nonlocal timerif timer:            timer.cancel()        timer = Timer(delay, func, args, kwargs)        timer.start()return wrapper

练习 3:实现深拷贝

// JavaScriptconst deepClone = (obj) =>JSON.parse(JSON.stringify(obj));
# Pythonimport copy# 方法1:内置函数deep_clone = copy.deepcopy(obj)# 方法2:JSON(和 JS 一样)import jsondeep_clone = json.loads(json.dumps(obj))

快速参考表

功能
JavaScript
Python
打印
console.log()print()
长度
arr.lengthlen(arr)
类型
typeof xtype(x)
转字符串
String(x)str(x)
转数字
Number(x)int(x)
 / float(x)
取整
Math.floor()int()
幂运算
Math.pow(2, 3)2 ** 3
取余
5 % 25 % 2
逻辑与
&&and
逻辑或
||or
逻辑非
!not
相等
=====
不等
!==!=
包含
arr.includes(x)x in arr

学习资源

在线练习

  • LeetCode - Python 刷题
  • Python Tutor - 可视化执行
  • Repl.it - 在线编程

推荐教程

  • Python 官方教程
  • Python for JavaScript Developers
  • Real Python - 实战教程

备忘单

  • Python 备忘单
  • JavaScript to Python


FastAPI路由详解

1. APIRouter基础概念

核心概念:APIRouter是FastAPI的路由分组器,类似Express的Router或React Router的路由配置。

JavaScript vs Python 路由对比

// Express.js - 你可能见过的后端路由const express = require('express');const router = express.Router();// 路由前缀router.use('/api/users');// 定义接口router.get('/', (req, res) => {  res.json({ users: [] });});router.post('/', (req, res) => {  res.json({ message"Created" });});// 注册到主应用app.use(router);// 最终路径:/api/users/
# FastAPI - Python后端路由from fastapi import APIRouter# 创建路由器(指定前缀和标签)router = APIRouter(    prefix="/api/users",    # 路由前缀    tags=["用户管理"]        # Swagger文档分类标签)# 定义接口@router.get("/")asyncdefget_users():return {"users": []}@router.post("/")asyncdefcreate_user(user: UserCreate):return {"message""Created"}# 注册到主应用(在app.py中)app.include_router(router)# 最终路径:/api/users/

2. 路由路径拼接规则

拼接公式

完整URL = 应用前缀 + Router前缀 + 方法路径示例:= (可选)     + /api/users + /list= /api/users/list

实战案例:理解多级路由

# === main.py - 主应用 ===from fastapi import FastAPIfrom routers import user_router, product_routerapp = FastAPI()# 场景1:直接注册(无额外前缀)app.include_router(user_router.router)# user_router的接口:/api/users/xxx# 场景2:添加统一前缀app.include_router(    product_router.router,    prefix="/v1"# 添加版本前缀)# product_router的接口:/v1/api/products/xxx# === user_router.py - 用户路由 ===router = APIRouter(    prefix="/api/users",      # Router前缀    tags=["用户管理"])@router.get("/list")          # 方法路径asyncdefget_user_list():return {"users": []}# 完整路径:/api/users/list@router.get("/{user_id}")     # 路径参数asyncdefget_user(user_id: str):return {"user_id": user_id}# 完整路径:/api/users/123# 访问:GET /api/users/123# === product_router.py - 产品路由 ===router = APIRouter(    prefix="/api/products",    tags=["产品管理"])@router.get("/")asyncdefget_products():return {"products": []}# 注册时添加了/v1前缀# 完整路径:/v1/api/products/

3. 多个Router的实际应用

案例:区分认证和公开接口

# === message_router.py ===from fastapi import APIRouter, Depends# Router 1:需要认证的接口auth_router = APIRouter(    prefix="/api/private",    tags=["私有接口"])@auth_router.post("/message")asyncdefprivate_message(    content: str,    user_id: str = Depends(get_current_user)# 需要登录):return {"message"f"用户{user_id}说:{content}"}# 完整路径:/api/private/message# 访问时需要:Authorization: Bearer <token># Router 2:公开接口(不需要认证)public_router = APIRouter(    prefix="/api/public",    tags=["公开接口"])@public_router.post("/message")asyncdefpublic_message(content: str):return {"message"f"访客说:{content}"}# 完整路径:/api/public/message# 访问时不需要token# === main.py - 主应用 ===app = FastAPI()app.include_router(auth_router)      # 注册认证路由app.include_router(public_router)    # 注册公开路由# 现在有两个消息接口:# POST /api/private/message  - 需要登录# POST /api/public/message   - 不需要登录

4. 路由参数详解

# 路径参数(Path Parameter)- 类似RESTful风格@router.get("/users/{user_id}")asyncdefget_user(user_id: str):return {"user_id": user_id}# 访问:GET /users/123# user_id = "123"# 查询参数(Query Parameter)@router.get("/users")asyncdefsearch_users(    name: str = None,           # 可选参数    age: int = None,    limit: int = 10# 默认值):return {"name": name, "age": age}# 访问:GET /users?name=张三&age=25&limit=20# 请求体(Request Body)from pydantic import BaseModelclassCreateUserRequest(BaseModel):    name: str    email: str    age: int@router.post("/users")asyncdefcreate_user(user: CreateUserRequest):return {"message"f"创建用户: {user.name}"}# 访问:POST /users# Body: {"name": "张三", "email": "...", "age": 25}

5. tags的作用:API文档分组

# 定义多个路由组user_router = APIRouter(prefix="/users", tags=["用户管理"])product_router = APIRouter(prefix="/products", tags=["产品管理"])order_router = APIRouter(prefix="/orders", tags=["订单管理"])# 在Swagger文档(/docs)中,接口会按标签分组显示:# 📁 用户管理#   - GET /users#   - POST /users#   - DELETE /users/{id}# 📁 产品管理#   - GET /products#   - POST /products# 📁 订单管理#   - GET /orders#   - POST /orders

6. 前端视角:如何调用这些接口

// 前端代码// 调用接口1:公开消息(不需要token)asyncfunctionpublicMessage(content{const response = await fetch('/api/public/message', {method'POST',headers: {'Content-Type''application/json'    },bodyJSON.stringify({ content })  });return response.json();}// 调用接口2:私有消息(需要token)asyncfunctionprivateMessage(content, token{const response = await fetch('/api/private/message', {method'POST',headers: {'Content-Type''application/json','Authorization'`Bearer ${token}`// 携带token    },bodyJSON.stringify({ content })  });return response.json();}

7. 实战案例:完整的路由模块

# === user_router.py - 用户管理路由 ===from fastapi import APIRouter, HTTPException, Queryfrom pydantic import BaseModelfrom typing import List, Optional# 创建路由器router = APIRouter(    prefix="/api/users",    tags=["用户管理"],    responses={404: {"description""用户不存在"}})# 请求/响应模型classUser(BaseModel):    id: str    name: str    email: str    age: intclassCreateUserRequest(BaseModel):    name: str    email: str    age: int# 模拟数据库USERS_DB = []# 接口1:获取用户列表@router.get("/", response_model=List[User])asyncdefget_users(    skip: int = Query(0, ge=0, description="跳过数量"),    limit: int = Query(10, ge=1, le=100, description="每页数量")):"""    获取用户列表    - skip: 跳过的数量(分页用)    - limit: 返回的数量(最多100)    """return USERS_DB[skip:skip+limit]# 接口2:获取单个用户@router.get("/{user_id}", response_model=User)asyncdefget_user(user_id: str):"""根据ID获取用户"""    user = next((u for u in USERS_DB if u["id"] == user_id), None)ifnot user:raise HTTPException(status_code=404, detail="用户不存在")return user# 接口3:创建用户@router.post("/", response_model=User)asyncdefcreate_user(user: CreateUserRequest):"""创建新用户"""    new_user = {"id": str(len(USERS_DB) + 1),        **user.dict()    }    USERS_DB.append(new_user)return new_user# 接口4:删除用户@router.delete("/{user_id}")asyncdefdelete_user(user_id: str):"""删除用户"""global USERS_DB    USERS_DB = [u for u in USERS_DB if u["id"] != user_id]return {"message""删除成功"}# === 在 app.py 中注册 ===app.include_router(router)# === 可访问的接口 ===# GET    /api/users/              - 获取列表# GET    /api/users/123           - 获取单个# POST   /api/users/              - 创建# DELETE /api/users/123           - 删除

关键点总结

概念
JavaScript
Python/FastAPI
路由分组express.Router()APIRouter()
路径前缀router.use('/prefix')prefix="/prefix"
文档标签
手动添加
tags=["标签"]
导入模块import router from './file'from path import router
模块内容
export显式声明
顶层定义都可访问
私有约定
不export
下划线前缀

高级特性

1. 列表推导式(List Comprehensions)

核心概念:Python最优雅的特性之一,可以用一行代码完成复杂的列表操作。

// JavaScript - 传统方式const numbers = [12345];// 平方const squares = numbers.map(x => x ** 2);// 筛选偶数const evens = numbers.filter(x => x % 2 === 0);// 筛选+转换const doubledEvens = numbers  .filter(x => x % 2 === 0)  .map(x => x * 2);
# Python - 列表推导式numbers = [12345]# 平方(基本语法:[表达式 for 变量 in 可迭代对象])squares = [x ** 2for x in numbers]  # [1, 4, 9, 16, 25]# 筛选偶数(带条件:[表达式 for 变量 in 可迭代对象 if 条件])evens = [x for x in numbers if x % 2 == 0]  # [2, 4]# 筛选+转换(一行搞定)doubled_evens = [x * 2for x in numbers if x % 2 == 0]  # [4, 8]# 嵌套循环matrix = [[12], [34], [56]]flat = [num for row in matrix for num in row]  # [1, 2, 3, 4, 5, 6]# 条件表达式labels = ["偶数"if x % 2 == 0else"奇数"for x in numbers]# ['奇数', '偶数', '奇数', '偶数', '奇数']

实战案例:处理API数据

# 从API返回的用户列表中提取成年人的名字users = [    {"name""张三""age"25},    {"name""李四""age"17},    {"name""王五""age"30}]# 传统方式adult_names = []for user in users:if user["age"] >= 18:        adult_names.append(user["name"])# 列表推导式(一行搞定)adult_names = [user["name"for user in users if user["age"] >= 18]# ['张三', '王五']

2. 字典推导式和集合推导式

// JavaScriptconst numbers = [12345];// 创建字典const squares = Object.fromEntries(  numbers.map(x => [x, x ** 2]));// {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}// 去重const unique = [...new Set([122333])];
# Python - 字典推导式numbers = [12345]# 字典推导式squares = {x: x ** 2for x in numbers}# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 筛选条件even_squares = {x: x ** 2for x in numbers if x % 2 == 0}# {2: 4, 4: 16}# 集合推导式unique = {x % 3for x in range(10)}  # {0, 1, 2}# 实战:转换键值对scores = {"语文"85"数学"90"英语"88}grades = {subject: "A"if score >= 90else"B"for subject, score in scores.items()}# {'语文': 'B', '数学': 'A', '英语': 'B'}

3. 生成器(Generator)

核心概念:节省内存的迭代器,只在需要时生成值。

// JavaScript - 生成器functionnumberGenerator({for (let i = 0; i < 5; i++) {yield i;  }}const gen = numberGenerator();console.log(gen.next().value);  // 0console.log(gen.next().value);  // 1
# Python - 生成器(更常用)# 方式1:生成器函数defnumber_generator():for i in range(5):yield igen = number_generator()print(next(gen))  # 0print(next(gen))  # 1# 方式2:生成器表达式(类似列表推导式,但用圆括号)squares = (x ** 2for x in range(1000000))  # 不占用太多内存print(next(squares))  # 0print(next(squares))  # 1# 实战:读取大文件defread_large_file(file_path):"""逐行读取大文件,不会一次性加载到内存"""with open(file_path) as f:for line in f:yield line.strip()# 使用for line in read_large_file('huge_file.txt'):    process(line)  # 每次只处理一行

4. 装饰器(Decorator)

核心概念:修改函数行为的高阶函数,类似JavaScript的高阶组件。

// JavaScript - 高阶函数functionlogTime(func{returnfunction(...args{const start = Date.now();const result = func(...args);console.log(`执行时间: ${Date.now() - start}ms`);return result;  };}// 使用const slowFunction = logTime(function(n{// 耗时操作return n * 2;});
# Python - 装饰器(语法糖)import timedeflog_time(func):"""装饰器:记录函数执行时间"""defwrapper(*args, **kwargs):        start = time.time()        result = func(*args, **kwargs)        print(f"执行时间: {time.time() - start:.2f}秒")return resultreturn wrapper# 使用装饰器(@语法)@log_timedefslow_function(n):    time.sleep(1)return n * 2# 调用时自动记录时间result = slow_function(5)  # 打印: 执行时间: 1.00秒# 等价于slow_function = log_time(slow_function)

实战案例:多个装饰器

defrequire_auth(func):"""装饰器:检查用户是否登录"""defwrapper(*args, **kwargs):ifnot is_logged_in():raise Exception("请先登录")return func(*args, **kwargs)return wrapperdeflog_action(func):"""装饰器:记录操作日志"""defwrapper(*args, **kwargs):        print(f"调用函数: {func.__name__}")        result = func(*args, **kwargs)        print(f"返回结果: {result}")return resultreturn wrapper# 多个装饰器(从下往上执行)@log_action@require_authdefdelete_user(user_id):returnf"删除用户 {user_id}"# 等价于# delete_user = log_action(require_auth(delete_user))

5. 上下文管理器(with语句)

核心概念:自动管理资源(如文件、数据库连接),确保正确清理。

// JavaScript - 手动管理资源const fs = require('fs');// 必须手动关闭const file = fs.openSync('file.txt''r');try {const content = fs.readFileSync(file, 'utf8');console.log(content);finally {  fs.closeSync(file);  // 确保关闭}
# Python - with语句自动管理# 文件操作(自动关闭)with open('file.txt''r', encoding='utf-8'as f:    content = f.read()    print(content)# 离开with块后,文件自动关闭# 多个资源with open('input.txt'as infile, open('output.txt''w'as outfile:    content = infile.read()    outfile.write(content.upper())# 数据库连接示例with get_db_connection() as conn:    cursor = conn.cursor()    cursor.execute("SELECT * FROM users")    results = cursor.fetchall()# 连接自动关闭# 自定义上下文管理器classTimer:def__enter__(self):        self.start = time.time()return selfdef__exit__(self, *args):        print(f"耗时: {time.time() - self.start:.2f}秒")# 使用with Timer():    time.sleep(1)    print("执行任务")# 输出: 耗时: 1.00秒

实战项目

项目1:API数据处理器

"""需求:从API获取用户数据,筛选成年用户,按年龄排序,生成报告"""import requestsfrom typing import List, Dictfrom datetime import datetimeclassUserDataProcessor:def__init__(self, api_url: str):        self.api_url = api_urldeffetch_users(self) -> List[Dict]:"""获取用户数据"""        response = requests.get(self.api_url)return response.json()deffilter_adults(self, users: List[Dict]) -> List[Dict]:"""筛选成年用户(使用列表推导式)"""return [user for user in users if user.get('age'0) >= 18]defsort_by_age(self, users: List[Dict]) -> List[Dict]:"""按年龄排序"""return sorted(users, key=lambda u: u['age'], reverse=True)defgenerate_report(self, users: List[Dict]) -> str:"""生成报告"""        report = ["=" * 50,f"用户报告 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}","=" * 50,f"总人数: {len(users)}",""        ]for i, user in enumerate(users, 1):            report.append(f"{i}{user['name']} - {user['age']}岁 "f"({user.get('email''无邮箱')})"            )return"\n".join(report)defprocess(self):"""主流程"""        print("正在获取数据...")        users = self.fetch_users()        print("正在筛选成年用户...")        adults = self.filter_adults(users)        print("正在排序...")        sorted_users = self.sort_by_age(adults)        print("正在生成报告...")        report = self.generate_report(sorted_users)# 保存报告with open('user_report.txt''w', encoding='utf-8'as f:            f.write(report)        print("报告已保存到 user_report.txt")return report# 使用processor = UserDataProcessor('https://api.example.com/users')report = processor.process()print(report)

项目2:配置文件管理器

"""需求:读取YAML配置文件,支持环境变量替换,提供便捷访问"""import osimport yamlfrom typing import AnyclassConfigManager:def__init__(self, config_file: str, env: str = 'dev'):        self.config_file = config_file        self.env = env        self.config = self._load_config()def_load_config(self) -> dict:"""加载配置文件"""with open(self.config_file, 'r', encoding='utf-8'as f:            config = yaml.safe_load(f)# 替换环境变量return self._replace_env_vars(config)def_replace_env_vars(self, obj: Any) -> Any:"""递归替换环境变量"""if isinstance(obj, dict):return {k: self._replace_env_vars(v) for k, v in obj.items()}elif isinstance(obj, list):return [self._replace_env_vars(item) for item in obj]elif isinstance(obj, str) and obj.startswith('${'and obj.endswith('}'):# ${ENV_VAR} 格式            var_name = obj[2:-1]return os.getenv(var_name, obj)return objdefget(self, key: str, default: Any = None) -> Any:"""获取配置值(支持点号分隔的路径)"""        keys = key.split('.')        value = self.configfor k in keys:if isinstance(value, dict):                value = value.get(k)if value isNone:return defaultelse:return defaultreturn valuedef__getitem__(self, key: str) -> Any:"""支持字典式访问"""return self.get(key)# 使用config = ConfigManager('config.yaml')# 获取配置db_host = config.get('database.host''localhost')api_key = config['api.key']print(f"数据库地址: {db_host}")print(f"API密钥: {api_key}")

常见陷阱

陷阱1:可变默认参数

# ❌ 错误示例defadd_item(item, items=[]):    items.append(item)return items# 问题:默认参数只创建一次print(add_item(1))  # [1]print(add_item(2))  # [1, 2] - 不是 [2]!# ✅ 正确做法defadd_item(item, items=None):if items isNone:        items = []    items.append(item)return itemsprint(add_item(1))  # [1]print(add_item(2))  # [2] - 正确

陷阱2:闭包中的变量

# ❌ 错误示例functions = []for i in range(3):    functions.append(lambda: i)# 所有函数都返回2(最后的i值)for func in functions:    print(func())  # 2, 2, 2# ✅ 正确做法1:使用默认参数functions = []for i in range(3):    functions.append(lambda x=i: x)for func in functions:    print(func())  # 0, 1, 2# ✅ 正确做法2:使用列表推导式functions = [lambda x=i: x for i in range(3)]

陷阱3:浅拷贝 vs 深拷贝

import copy# 浅拷贝original = [[12], [34]]shallow = original.copy()  # 或 original[:]shallow[0][0] = 999print(original)  # [[999, 2], [3, 4]] - 被修改了!# 深拷贝original = [[12], [34]]deep = copy.deepcopy(original)deep[0][0] = 999print(original)  # [[1, 2], [3, 4]] - 没被修改

继续学习

立即实践

# 练习1:写一个函数,统计字符串中每个字符出现的次数defcount_chars(text):return {char: text.count(char) for char in set(text)}# 练习2:写一个装饰器,让函数重试3次defretry(times=3):defdecorator(func):defwrapper(*args, **kwargs):for i in range(times):try:return func(*args, **kwargs)except Exception as e:if i == times - 1:raise                    print(f"重试 {i+1}/{times}")return wrapperreturn decorator# 练习3:用with语句实现一个计时器classTimer:def__enter__(self):import time        self.start = time.time()return selfdef__exit__(self, *args):        print(f"耗时: {time.time() - self.start:.2f}秒")

记住:编程语言只是工具,重要的是解决问题的思维方式!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-28 04:40:32 HTTP/2.0 GET : https://f.mffb.com.cn/a/483417.html
  2. 运行时间 : 0.206612s [ 吞吐率:4.84req/s ] 内存消耗:4,995.20kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=efe4e26e75301a55427620da52a815e6
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001090s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001534s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000773s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.003835s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001367s ]
  6. SELECT * FROM `set` [ RunTime:0.001372s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001745s ]
  8. SELECT * FROM `article` WHERE `id` = 483417 LIMIT 1 [ RunTime:0.008098s ]
  9. UPDATE `article` SET `lasttime` = 1774644032 WHERE `id` = 483417 [ RunTime:0.006627s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000608s ]
  11. SELECT * FROM `article` WHERE `id` < 483417 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001025s ]
  12. SELECT * FROM `article` WHERE `id` > 483417 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001106s ]
  13. SELECT * FROM `article` WHERE `id` < 483417 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008743s ]
  14. SELECT * FROM `article` WHERE `id` < 483417 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002684s ]
  15. SELECT * FROM `article` WHERE `id` < 483417 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006044s ]
0.210500s