当前位置: 首页 > news >正文

《Python函数:从入门到精通,一文掌握函数编程精髓》

坚持用 清晰易懂的图解 + 代码语言,让每个知识点变得简单!
🚀呆头个人主页详情
🌱 呆头个人Gitee代码仓库
📌 呆头详细专栏系列
座右铭: “不患无位,患所以立。”在这里插入图片描述


Python函数:从入门到精通,一文掌握函数编程精髓

  • 前言
  • 目录
  • 一、函数是什么
    • 1.函数的基本语法
  • 二、函数参数
    • 1.位置参数
    • 2.默认参数
    • 3.关键字参数
    • 4.可变参数
    • 5.关键字可变参数
    • 6.参数类型对比
  • 三、函数返回值
    • 1.单值返回
    • 2.多值返回
    • 3.无返回值函数
  • 四、变量作用域
    • 1.局部变量与全局变量
    • 2.使用global关键字
    • 3.变量作用域可视化
  • 五、函数的高级特性
    • 1.函数作为对象
    • 2.嵌套函数
    • 3.闭包
    • 4.装饰器
    • 5.装饰器工作原理
  • 六、函数的应用场景
    • 1.数据处理
    • 2.代码复用
    • 3.回调函数
    • 4.函数执行过程
  • 七、函数参数传递机制
    • 1.可变对象与不可变对象
    • 2.参数传递机制可视化
  • 八、函数设计最佳实践
    • 1.单一职责原则
    • 2.函数命名
    • 3.参数设计
    • 4.文档字符串
  • 九、函数调试技巧
    • 1.打印调试
    • 2.使用断言
    • 3.使用日志
  • 十、函数性能优化
    • 1.避免重复计算
    • 2.使用生成器
    • 3.使用适当的数据结构
  • 十一、函数式编程
    • 1.lambda函数
    • 2.map、filter和reduce
    • 3.列表推导式
  • 十二、函数的常见错误与陷阱
    • 1.默认参数陷阱
    • 2.变量作用域问题
    • 3.递归深度限制
  • 总结
    • 参考链接
    • 关键词标签


前言

🔥 “灵根检测发现:阁下竟是万中无一的编程奇才!”

这是一个用修仙世界观解构Python学习的硬核专栏:

  • 练气期:变量/循环/函数(基础心法)
  • 筑基期:面向对象/异常处理(护体罡气)
  • 金丹期:爬虫/数据分析(神通初成)
  • 元婴期:Django/机器学习(开辟紫府)

✍️ 你将获得:
✅ 每章配套「渡劫雷法」(实战项目)
✅ 避免走火入魔的「心魔警示」(避坑指南)
✅ 飞升大能的「神识传承」(大佬代码赏析)

“三千大道,Py为尊。本座在此布道,助你斩尽BUG,证道代码金仙!”

(正文开始👇)


目录

一、函数是什么

函数本质上是一段可重用的代码块,它接收输入(参数),执行特定任务,并返回结果。在Python中,函数不仅仅是组织代码的方式,更是实现抽象和封装的重要工具。

1.函数的基本语法

Python函数定义的基本语法如下:

def 函数名(参数1, 参数2, ...):"""文档字符串:描述函数功能"""# 函数体return 返回值  # 可选

一个简单的函数示例:

def greet(name):"""向指定的人打招呼"""return f"你好,{name}!"# 调用函数
message = greet("小明")
print(message)  # 输出:你好,小明!

在这个例子中,greet是函数名,name是参数,函数体很简单,只有一行代码,返回一个格式化的字符串。

二、函数参数

Python函数的参数系统非常灵活,提供了多种参数类型来满足不同的需求。

1.位置参数

最基本的参数类型,调用时按照定义的顺序传递参数值。

def power(base, exponent):"""计算base的exponent次方"""return base ** exponentresult = power(2, 3)  # 2的3次方 = 8
print(result)  # 输出:8

2.默认参数

为参数提供默认值,调用时可以省略这些参数。

def power(base, exponent=2):"""默认计算平方"""return base ** exponentprint(power(3))     # 3的2次方 = 9
print(power(3, 4))  # 3的4次方 = 81

3.关键字参数

通过参数名指定参数值,可以不按顺序传参。

def describe_pet(animal_type, pet_name):"""描述宠物信息"""return f"我有一只{animal_type},它叫{pet_name}。"# 使用关键字参数
print(describe_pet(pet_name="球球", animal_type="猫"))  # 输出:我有一只猫,它叫球球。

4.可变参数

使用*args接收任意数量的位置参数,以元组形式存储。

def sum_all(*numbers):"""计算所有参数的和"""total = 0for num in numbers:total += numreturn totalprint(sum_all(1, 2, 3, 4, 5))  # 输出:15

5.关键字可变参数

使用**kwargs接收任意数量的关键字参数,以字典形式存储。

def build_profile(**user_info):"""创建用户资料字典"""return user_infoprofile = build_profile(name="小明", age=25, city="北京", hobby="编程")
print(profile)  # 输出:{'name': '小明', 'age': 25, 'city': '北京', 'hobby': '编程'}

6.参数类型对比

下面的表格总结了Python函数的不同参数类型:

参数类型语法示例特点
位置参数def func(param1, param2)func(1, 2)必须按顺序提供所有参数
默认参数def func(param1, param2=value)func(1)func(1, 3)可选参数,有默认值
关键字参数def func(param1, param2)func(param2=2, param1=1)通过参数名指定,顺序灵活
可变位置参数def func(*args)func(1, 2, 3, 4)接收任意数量的位置参数
关键字可变参数def func(**kwargs)func(a=1, b=2, c=3)接收任意数量的关键字参数

三、函数返回值

Python函数可以返回单个值、多个值,或者不返回任何值(默认返回None)。

1.单值返回

最常见的返回形式,函数执行完毕后返回一个值。

def square(number):"""返回数字的平方"""return number ** 2result = square(4)
print(result)  # 输出:16

2.多值返回

Python函数可以同时返回多个值,实际上是返回一个元组。

def get_dimensions(length, width):"""计算矩形的周长和面积"""perimeter = 2 * (length + width)area = length * widthreturn perimeter, areap, a = get_dimensions(5, 3)
print(f"周长:{p},面积:{a}")  # 输出:周长:16,面积:15

3.无返回值函数

如果函数没有return语句,或者return后面没有表达式,函数将返回None

def greet(name):"""打印问候语,无返回值"""print(f"你好,{name}!")result = greet("小红")  # 打印:你好,小红!
print(result)  # 输出:None

四、变量作用域

理解变量作用域对于编写正确的函数至关重要。Python中有局部作用域和全局作用域。

1.局部变量与全局变量

# 全局变量
message = "你好,世界!"def greet():# 局部变量name = "小明"print(f"{message} {name}")greet()  # 输出:你好,世界! 小明
# print(name)  # 错误:name不在全局作用域中

2.使用global关键字

使用global关键字可以在函数内部修改全局变量。

counter = 0def increment():global countercounter += 1return counterprint(increment())  # 输出:1
print(increment())  # 输出:2
print(counter)      # 输出:2

3.变量作用域可视化

函数作用域
全局作用域
局部变量
使用global?
修改全局变量
仅在函数内有效
函数调用
全局变量
函数结束

图1:变量作用域图 - 展示了Python中全局变量和局部变量的作用范围及相互影响

五、函数的高级特性

Python函数具有许多高级特性,使其成为一种强大的编程工具。

1.函数作为对象

在Python中,函数是一等公民,可以像其他对象一样被赋值、传递和返回。

def greet(name):return f"你好,{name}!"# 函数赋值给变量
say_hello = greet
print(say_hello("小明"))  # 输出:你好,小明!# 函数作为参数传递
def apply_function(func, value):return func(value)result = apply_function(greet, "小红")
print(result)  # 输出:你好,小红!

2.嵌套函数

在函数内部定义另一个函数,内部函数可以访问外部函数的变量。

def outer_function(x):"""外部函数"""def inner_function(y):"""内部函数"""return x + yreturn inner_functionadd_five = outer_function(5)
print(add_five(3))  # 输出:8
print(add_five(7))  # 输出:12

3.闭包

闭包是一个函数,它记住了创建它时的环境。

def make_multiplier(factor):"""创建一个乘法器"""def multiplier(number):return number * factorreturn multiplierdouble = make_multiplier(2)
triple = make_multiplier(3)print(double(5))  # 输出:10
print(triple(5))  # 输出:15

4.装饰器

装饰器是一种特殊的函数,它接受一个函数作为参数并返回一个新函数。

def timer_decorator(func):"""计时装饰器"""import timedef wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()print(f"函数 {func.__name__} 执行时间:{end_time - start_time:.4f} 秒")return resultreturn wrapper@timer_decorator
def slow_function():"""一个耗时的函数"""import timetime.sleep(1)return "函数执行完毕"print(slow_function())
# 输出:
# 函数 slow_function 执行时间:1.0010 秒
# 函数执行完毕

5.装饰器工作原理

客户端代码@decoratororiginal_functionwrapper_function1. 定义函数并应用装饰器2. 接收原始函数3. 创建包装函数4. 定义增强功能5. 返回包装函数6. 调用函数(实际调用包装函数)7. 调用原始函数8. 返回结果9. 返回增强后的结果装饰器在不修改原函数代码的情况下增加新功能客户端代码@decoratororiginal_functionwrapper_function

图2:装饰器工作原理时序图 - 展示了Python装饰器的执行流程和工作机制

六、函数的应用场景

Python函数在不同场景下有着广泛的应用。下面我们来看几个典型的应用场景。

1.数据处理

函数可以用于处理和转换数据。

def process_data(data_list):"""处理数据列表,返回处理后的结果"""results = []for item in data_list:# 数据处理逻辑processed = item * 2 + 1results.append(processed)return resultsdata = [1, 2, 3, 4, 5]
processed_data = process_data(data)
print(processed_data)  # 输出:[3, 5, 7, 9, 11]

2.代码复用

函数是实现代码复用的基本单位。

def calculate_area(shape, *dimensions):"""计算不同形状的面积"""if shape == "rectangle":return dimensions[0] * dimensions[1]elif shape == "circle":import mathreturn math.pi * dimensions[0] ** 2elif shape == "triangle":return 0.5 * dimensions[0] * dimensions[1]else:return None# 计算不同形状的面积
rectangle_area = calculate_area("rectangle", 5, 4)
circle_area = calculate_area("circle", 3)
triangle_area = calculate_area("triangle", 6, 8)print(f"矩形面积:{rectangle_area}")  # 输出:矩形面积:20
print(f"圆形面积:{circle_area:.2f}")  # 输出:圆形面积:28.27
print(f"三角形面积:{triangle_area}")  # 输出:三角形面积:24.0

3.回调函数

函数可以作为参数传递给其他函数,实现回调机制。

def apply_operation(numbers, operation):"""对数字列表应用指定操作"""return [operation(num) for num in numbers]def square(x):return x ** 2def cube(x):return x ** 3numbers = [1, 2, 3, 4, 5]
squared = apply_operation(numbers, square)
cubed = apply_operation(numbers, cube)print(f"平方结果:{squared}")  # 输出:平方结果:[1, 4, 9, 16, 25]
print(f"立方结果:{cubed}")    # 输出:立方结果:[1, 8, 27, 64, 125]

4.函数执行过程

让我们通过一个图表来可视化函数的执行过程:

函数系统
调用阶段
调用阶段
系统
创建函数调用栈帧
创建函数调用栈帧
系统
传递参数
传递参数
系统
绑定参数到形参
绑定参数到形参
执行阶段
执行阶段
函数
执行函数体代码
执行函数体代码
函数
遇到return语句
遇到return语句
函数
计算返回值
计算返回值
返回阶段
返回阶段
系统
销毁局部变量
销毁局部变量
系统
返回值传递给调用者
返回值传递给调用者
系统
恢复调用点执行
恢复调用点执行
函数执行旅程

图4:函数执行旅程图 - 展示了Python函数从调用到返回的完整执行过程

七、函数参数传递机制

Python的参数传递机制是"传对象引用",这意味着函数接收的是对象的引用,而不是对象的副本。

1.可变对象与不可变对象

理解可变对象和不可变对象对于理解函数参数传递至关重要。

# 不可变对象作为参数
def modify_string(s):s = s + " World"print(f"函数内部:{s}")text = "Hello"
modify_string(text)
print(f"函数外部:{text}")
# 输出:
# 函数内部:Hello World
# 函数外部:Hello# 可变对象作为参数
def modify_list(lst):lst.append(4)print(f"函数内部:{lst}")numbers = [1, 2, 3]
modify_list(numbers)
print(f"函数外部:{numbers}")
# 输出:
# 函数内部:[1, 2, 3, 4]
# 函数外部:[1, 2, 3, 4]

2.参数传递机制可视化

60%25%10%5%不同类型参数在Python中的分布不可变参数可变参数默认参数关键字可变参数

图5:参数类型分布饼图 - 展示了Python中不同类型参数的使用比例

八、函数设计最佳实践

编写高质量的函数需要遵循一些最佳实践。

1.单一职责原则

每个函数应该只做一件事,并且做好。

# 不好的设计:函数做了太多事情
def process_and_save_data(data, filename):# 处理数据processed_data = []for item in data:processed_data.append(item * 2)# 保存数据with open(filename, 'w') as f:for item in processed_data:f.write(f"{item}\n")return processed_data# 好的设计:职责分离
def process_data(data):"""只负责处理数据"""return [item * 2 for item in data]def save_data(data, filename):"""只负责保存数据"""with open(filename, 'w') as f:for item in data:f.write(f"{item}\n")# 使用
data = [1, 2, 3, 4, 5]
processed = process_data(data)
save_data(processed, "output.txt")

2.函数命名

函数名应该清晰地表达函数的功能,通常使用动词或动词短语。

# 不好的命名
def x(a, b):return a + b# 好的命名
def add_numbers(a, b):return a + b

3.参数设计

函数参数应该设计得直观且易于使用。

# 不好的参数设计
def create_user(p1, p2, p3, p4, p5):# ...pass# 好的参数设计
def create_user(username, email, password, first_name=None, last_name=None):# ...pass

4.文档字符串

为函数添加文档字符串,说明函数的功能、参数和返回值。

def calculate_discount(price, discount_rate):"""计算折扣后的价格。参数:price (float): 原始价格discount_rate (float): 折扣率,0到1之间的小数返回:float: 折扣后的价格示例:>>> calculate_discount(100, 0.2)80.0"""if not 0 <= discount_rate <= 1:raise ValueError("折扣率必须在0到1之间")return price * (1 - discount_rate)

“函数应该做一件事,只做一件事,并且把这件事做好。” —— Robert C. Martin(Uncle Bob)

九、函数调试技巧

调试函数是编程过程中不可避免的一部分。以下是一些有用的调试技巧。

1.打印调试

最简单的调试方法是使用print语句输出变量值和执行流程。

def complex_calculation(a, b, c):print(f"输入参数: a={a}, b={b}, c={c}")intermediate = a * bprint(f"中间结果: {intermediate}")result = intermediate / cprint(f"最终结果: {result}")return resulttry:complex_calculation(5, 2, 0)
except Exception as e:print(f"发生错误: {e}")

2.使用断言

断言可以帮助验证函数的前置条件和后置条件。

def divide(a, b):"""安全除法,确保除数不为零"""assert b != 0, "除数不能为零"return a / btry:result = divide(10, 0)
except AssertionError as e:print(f"断言错误: {e}")

3.使用日志

对于复杂的应用程序,使用日志比打印更灵活。

import logging# 配置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')def process_item(item):"""处理单个项目"""logging.debug(f"开始处理项目: {item}")try:result = item * 2logging.info(f"项目 {item} 处理成功,结果: {result}")return resultexcept Exception as e:logging.error(f"处理项目 {item} 时出错: {e}")raise# 使用函数
items = [1, 2, "3", 4]
for item in items:try:process_item(item)except Exception as e:logging.warning(f"跳过项目,继续处理下一个")

十、函数性能优化

优化函数性能可以从多个方面入手。

1.避免重复计算

使用缓存可以避免重复计算,提高性能。

# 使用字典作为缓存
fibonacci_cache = {}def fibonacci(n):"""计算斐波那契数列的第n项"""# 检查缓存if n in fibonacci_cache:return fibonacci_cache[n]# 计算值if n <= 1:value = nelse:value = fibonacci(n-1) + fibonacci(n-2)# 缓存结果fibonacci_cache[n] = valuereturn value# 使用functools.lru_cache装饰器
from functools import lru_cache@lru_cache(maxsize=128)
def fibonacci_optimized(n):"""使用lru_cache优化的斐波那契函数"""if n <= 1:return nreturn fibonacci_optimized(n-1) + fibonacci_optimized(n-2)# 比较性能
import timedef measure_time(func, *args):start = time.time()result = func(*args)end = time.time()print(f"{func.__name__} 执行时间: {end - start:.6f} 秒")return resultn = 35
measure_time(fibonacci, n)
measure_time(fibonacci_optimized, n)

2.使用生成器

对于处理大量数据的函数,使用生成器可以减少内存使用。

# 使用列表(一次性加载所有数据到内存)
def get_squares_list(n):"""返回0到n-1的平方列表"""return [i**2 for i in range(n)]# 使用生成器(按需生成数据)
def get_squares_generator(n):"""返回0到n-1的平方生成器"""for i in range(n):yield i**2# 使用列表
squares_list = get_squares_list(1000000)  # 立即分配大量内存# 使用生成器
squares_gen = get_squares_generator(1000000)  # 不分配额外内存
for i, square in enumerate(squares_gen):if i < 10:  # 只处理前10个print(square)else:break

3.使用适当的数据结构

选择合适的数据结构可以显著提高函数性能。

import time
import random# 准备测试数据
data = list(range(10000))
random.shuffle(data)
search_items = random.sample(data, 1000)# 使用列表查找
def find_in_list(items, search_items):found = 0for search_item in search_items:if search_item in items:  # 列表查找是O(n)found += 1return found# 使用集合查找
def find_in_set(items_set, search_items):found = 0for search_item in search_items:if search_item in items_set:  # 集合查找是O(1)found += 1return found# 比较性能
start = time.time()
found_list = find_in_list(data, search_items)
list_time = time.time() - startstart = time.time()
found_set = find_in_set(set(data), search_items)
set_time = time.time() - startprint(f"列表查找时间: {list_time:.6f} 秒")
print(f"集合查找时间: {set_time:.6f} 秒")
print(f"性能提升: {list_time/set_time:.2f}倍")

十一、函数式编程

Python支持函数式编程范式,提供了许多函数式编程的特性。

1.lambda函数

lambda函数是一种小型匿名函数,可以在需要函数对象的地方使用。

# 常规函数
def add(x, y):return x + y# 等价的lambda函数
add_lambda = lambda x, y: x + yprint(add(3, 5))       # 输出:8
print(add_lambda(3, 5))  # 输出:8

2.map、filter和reduce

这些高阶函数是函数式编程的核心。

# map:对列表中的每个元素应用函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared)  # 输出:[1, 4, 9, 16, 25]# filter:过滤列表中的元素
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出:[2, 4]# reduce:将列表中的元素累积为单个值
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 输出:120 (1*2*3*4*5)

3.列表推导式

列表推导式是一种简洁的创建列表的方式,可以替代map和filter的组合。

numbers = [1, 2, 3, 4, 5]# 使用map和filter
squared_evens = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))# 使用列表推导式
squared_evens_comp = [x**2 for x in numbers if x % 2 == 0]print(squared_evens)      # 输出:[4, 16]
print(squared_evens_comp)  # 输出:[4, 16]

十二、函数的常见错误与陷阱

编写函数时,有一些常见的错误和陷阱需要避免。

1.默认参数陷阱

使用可变对象作为默认参数值可能导致意外行为。

# 错误的做法
def add_item(item, items=[]):items.append(item)return itemsprint(add_item("apple"))  # 输出:['apple']
print(add_item("banana"))  # 输出:['apple', 'banana'] - 可能不是预期结果# 正确的做法
def add_item_fixed(item, items=None):if items is None:items = []items.append(item)return itemsprint(add_item_fixed("apple"))   # 输出:['apple']
print(add_item_fixed("banana"))  # 输出:['banana']

2.变量作用域问题

在函数内部引用外部变量时,需要注意作用域规则。

x = 10def update_x():x = 20  # 创建了一个局部变量x,而不是修改全局变量print(f"函数内部x = {x}")update_x()
print(f"函数外部x = {x}")
# 输出:
# 函数内部x = 20
# 函数外部x = 10def update_x_correctly():global xx = 20  # 修改全局变量print(f"函数内部x = {x}")update_x_correctly()
print(f"函数外部x = {x}")
# 输出:
# 函数内部x = 20
# 函数外部x = 20

3.递归深度限制

Python对递归深度有限制,超过限制会导致栈溢出。

import sys
print(f"最大递归深度: {sys.getrecursionlimit()}")def factorial(n):"""计算阶乘"""if n <= 1:return 1return n * factorial(n - 1)try:result = factorial(1000)  # 可能导致栈溢出
except RecursionError as e:print(f"递归错误: {e}")# 使用尾递归优化(Python不会自动优化尾递归)
def factorial_tail(n, acc=1):if n <= 1:return accreturn factorial_tail(n - 1, n * acc)# 或者使用循环代替递归
def factorial_loop(n):result = 1for i in range(1, n + 1):result *= ireturn result

总结

随着Python的不断发展,函数的特性也在不断丰富。类型提示、异步编程、函数式编程特性的引入,都为我们提供了更多的工具来编写高质量的代码。保持学习的热情,跟上这些新特性的步伐,才能在Python编程的道路上走得更远。

希望这篇文章能够帮助你更好地理解和使用Python函数,让我们一起用函数的力量,构建更加优雅、高效的Python程序!


📢 如果你也喜欢这种"不呆头"的技术风格:
👁️ 【关注】 看一个非典型程序员如何用野路子解决正经问题
👍 【点赞】 给"不写八股文"的技术分享一点鼓励
🔖 【收藏】 把这些"奇怪但有用"的代码技巧打包带走
💬 【评论】 来聊聊——你遇到过最"呆头"的 Bug 是啥?
🗳️ 【投票】 您的投票是支持我前行的动力
技术没有标准答案,让我们一起用最有趣的方式,写出最靠谱的代码! 🎮💻

参考链接

  1. Python官方文档 - 函数定义
  2. PEP 484 – Type Hints
  3. Python函数式编程指南
  4. Python装饰器的工作原理
  5. Python异步编程入门

关键词标签

#Python函数 #函数编程 #装饰器 #闭包 #异步函数 #函数式编程 #类型提示

http://www.lryc.cn/news/621313.html

相关文章:

  • Transformer网络结构解析
  • 《嵌入式 C 语言编码规范与工程实践个人笔记》参考华为C语言规范标准
  • CNN - 卷积层
  • GaussDB数据库架构师修炼(十六) 如何选择磁盘
  • 《算法导论》第 24 章 - 单源最短路径
  • 20250814 最小生成树总结
  • Java 大视界 -- Java 大数据机器学习模型在金融欺诈检测与防范策略制定中的应用(397)
  • 【Demo】AI-ModelScope/bert-base-uncase 模型训练及使用
  • 市面上有没有可以导入自有AI算法模型的低空平台?
  • pytorch学习笔记-Loss的使用、在神经网络中加入Loss、优化器(optimizer)的使用
  • Linux 对 YUM 包的管理
  • HTTPS 工作原理
  • Java使用Apache POI读取Excel文件
  • dkms安装nvidia驱动和多内核支持
  • label studio 服务器端打开+xshell端口转发设置
  • UniApp 中使用 tui-xecharts插件(或类似图表库如 uCharts)
  • 2025年Java大厂面试场景题全解析:高频考点与实战攻略
  • 20道DOM相关前端面试题
  • Java面试场景题大全精简版
  • VSCode打开新的文件夹之后当前打开的文件夹被覆盖
  • 树形DP详解
  • 基于springboot的信息化在线教学平台的设计与实现(源码+论文)
  • 2025天府杯数学建模C题
  • Python网络爬虫(二) - 解析静态网页
  • MFC的使用——使用ChartCtrl绘制曲线
  • 数据结构初阶(13)排序算法-选择排序(选择排序、堆排序)(动图演示)
  • 手机实时提取SIM卡打电话的信令声音-整体解决方案规划
  • 百度智能云x中科大脑:「城市智能体」如何让城市更会思考
  • pyecharts可视化图表-pie:从入门到精通
  • QT中ARGB32转ARGB4444优化4K图像性能的实现方案(完整源码)