ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

python函数模块的学习笔记

python函数模块的学习笔记

1-函数定义、参数传递与作用域(LEGB)

1.1 简介

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。

  • 函数代码块以def关键词开头,后接函数标识符名称和圆括号()。

  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

  • 函数内容以冒号:起始,并且缩进。

  • return [表达式]结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

1.2 创建与使用

# 1-函数的创建 # 1.1 语法格式: """ (1)定义一个函数 def 函数名(参数1, 参数2, ...): 函数体 return 返回值 (2)调用函数 函数名(参数1, 参数2, ...) """ # 需求:比较两个数的大小 # def 函数定义关键字 # compare 函数名---自定义,必须符合标识符的规则 # (a, b) 形参:局部变量,用于接收实参的值 # return 返回值---作用:1.结束函数的执行 2.将返回值传递给调用函数 def compare(a, b, c): # 函数体---业务逻辑 print("函数执行开始") if a > b: return a elif a < b: return b print("函数执行结束") # 调用函数---将实参传递给函数的形参 # 语法: 函数名(实参1, 实参2, ...) # 实参---实际传递给函数的值,也可以是变量、表达式等任意值 # 注意:实参的个数必须与形参的个数一致 num1 = 100 num2 = 20 max = compare(num1, num2) print(max)

1.3 作用域

1.3.1定义:

作用域(scope) 指的是变量可以被访问的有效范围。Python 中主要按以下规则来决定一个变量在哪里能用(即 LEGB 规则):

1.3.2 分类

全局作用域:变量的定义位置在函数外部,作用域范围是整个程序局部作用域:变量的定义位置在函数内部,作用域范围是该函数内部全局变量:在函数外部定义的变量,可以在函数内部使用,也可以在函数外部使用局部变量:在函数内部定义的变量,只能在函数内部使用,不能在函数外部使用

1.4 函数参数的分类

# 函数参数的分类使用 # 分类:必需参数、关键字参数、默认参数、不定长参数 # ======================================== # 1. 必需参数(位置参数) # 调用函数时,实参的个数和顺序必须与形参一一对应 # ======================================== def add(a, b): return a + b # 正确:实参与形参个数、顺序一致 print(add(10, 20)) # print(add(20)) # 错误:实参个数与形参不一致(会报错) # print(add(10)) # ======================================== # 2. 关键字参数 # 调用函数时,通过 "参数名=值" 的形式传参,可以不按形参的顺序 # ======================================== def introduce(name, age): print(f"我叫{name},今年{age}岁") # 位置参数 introduce("小明", 18) # 关键字参数:可以不按顺序 introduce(age=18, name="小明") # ======================================== # 3. 默认参数(缺省参数) # 定义形参时直接赋值,调用函数时可以不给该参数传值 # 注意:默认参数要放在必备参数之后 # ======================================== def info(name, age=18): print(f"我叫{name},默认年龄{age}岁") # info("小红") # name 用实参,age 用默认值 18 info(age=20, name="小红") # 两个都用实参 # # ======================================== # 4. 不定长参数 # 传参个数不固定 # *args 接收任意多个位置参数,打包成一个元组 # **kwargs 接收任意多个关键字参数,打包成一个字典 # ======================================== def sum_all(*args): print(*args, type(args)) print(args[0]) total = 0 for n in args: total += n # return total print(total) sum_all(1, 2, 3) # 6 sum_all(1, 2, 3, 4, 5) # 15 def show_info(*args, age=18, **kwargs): print(args, type(args)) print(kwargs, type(kwargs)) print(age, type(age)) show_info("小明", 2026, age=20, city="北京")

2-闭包机制与高级函数应用

2.1 闭包的介绍

核心概念:在一个函数内部再定义一个函数,内层函数用到了外层函数的变量,并且外层函数把内层函数返回出去,这就形成了闭包。

# 闭包函数 # 在一个函数内部再定义一个函数, # 内层函数用到了外层函数的变量, # 并且外层函数把内层函数返回出去, # 这就形成了闭包。 # 外层函数 def add(a, b): print(a, b) # 外层使用了a和b c = 100 # 内层函数 def inner(): # 内层函数用到了外层函数的变量, sum = a + b # 局部变量 return sum # print("内层函数对象inner:", inner) # 内层函数对象 # print("调用内层函数inner(),返回结果:", inner()) # 调用内层函数,返回结果 # 返回内层函数 return inner # 调用 result = add(1, 2) result()

2.2 nonlocal与nonlocal的区别

  • global= 管模块最顶层的变量("我就是要最外面那个")。

  • nonlocal= 管当前函数外层函数的变量("我要改我这个闭包外层的变量")。

  • 如果你的场景是闭包(函数套函数,内层要改外层),几乎总是用nonlocal;只有在内层明确要改模块顶层的全局变量时才用global。

count = 100 # 真正的全局变量(模块顶层) def make_counter(): count = 0 # make_counter 的局部变量 def counter(): global count # 找到模块顶层的 count = 100 count += 1 # 改的是外层那个 100,不是这里的 0 return count return counter
def make_counter(): count = 0 def counter(): nonlocal count # 指向 make_counter 里的 count count += 1 return count return counter

2.3 装饰器高级函数

核心概念:装饰器本质就是一个「接收函数、返回新函数」的函数,用于在不修改原函数代码的前提下,为其增加额外功能(如计时、日志、权限校验)。

不修改原函数的代码,只是在原函数的基础上,添加了新的功能。

# 装饰器---不修改原函数的代码,只是在原函数的基础上,添加了新的功能。 # **核心概念**: # 装饰器本质就是一个闭包函数, # 用于在不修改原函数代码的前提下,为其**增加额外功能**(如计时、日志、权限校验)。 # 不修改原函数的代码,只是在原函数的基础上,添加了新的功能。 def my_decorator(func): def wrapper(*args, **kwargs): # 不定长参数,适配任意函数 print("在函数执行前做点事...") result = func(*args, **kwargs) # 调用原函数 print("在函数执行后做点事...") return result # 把原函数的返回值返回出去 return wrapper # 自动语法糖调用装饰器 @装饰器函数---@闭包函数名称 @my_decorator def say_hello(): print("Hello!") @my_decorator def say_goodbye(): print("Goodbye!") @my_decorator def say_Hi(): print("Hi!") say_goodbye()

3.模块化、包管理与标准库导入

3.1 模块化

一个.py文件就是一个独立的模块

# mymath.py """我的数学工具模块""" PI = 3.14159 def add(a, b): return a + b class Circle: def __init__(self, r): self.r = r def area(self): return PI * self.r ** 2

3.2 标准导入

导包的常用方式

1.直接导入模块import---相同包下或者内置模块导入

import mymath print(mymath.add(1, 2))

2-from 包名 import 指定内容(变量,函数,类)as 别名 ---导入指定的函数、类、模块等

from mymath import add, Circle print(add(1, 2))

3.导入时起别名

import mymath as mm print(mm.add(1, 2))

3.3 python包和目录的区别

本质是多了__init__.py文件用来对于python模块的管理

project/ ├── main.py └── utils/ # 这是一个包 ├── __init__.py # 包的标志文件(可以空着) ├── string_tools.py └── file_tools.py
# 方式一:完整路径导入 from utils.string_tools import split_words # 方式二:相对导入(只能在包内部使用) # file_tools.py 内部引用同级模块 from .string_tools import split_words

4.datetime 模块的使用方式

作用:datetime是 Python 标准库中用于处理日期和时间的核心模块。它提供了面向对象的接口,可以方便地获取、创建、计算和格式化日期时间。

核心类:

类名作用示例
datetime.datetime同时包含日期和时间2026-10-31 14:30:00
datetime.date仅日期2026-10-31
datetime.time仅时间14:30:00
datetime.timedelta时间差(用于运算)加 3 天、减 2 小时

4.1获取当前时间

from datetime import datetime, date, time, timedelta now = datetime.now() # 2026-10-31 14:30:00.123456(本地时间) today = date.today() # 2026-10-31 utc_now = datetime.utcnow() # UTC 时间

4.2自定义创建时间

dt = datetime(2026, 10, 31, 14, 30, 0) # 指定年月日时分秒 d = date(2026, 10, 31) # 只指定日期

4.3时间运算(加减天数/时长)

dt = datetime(2026, 10, 31) print(dt + timedelta(days=3)) # 2026-11-03 00:00:00 print(dt - timedelta(hours=2)) # 2026-10-30 22:00:00 # 两个时间相减得到时间差 diff = datetime(2026, 11, 5) - datetime(2026, 10, 31) print(diff.days) # 5

4.4格式化与解析(字符串 ↔ 时间)

dt = datetime.now() # 时间 -> 字符串 s = dt.strftime("%Y-%m-%d %H:%M:%S") # "2026-10-31 14:30:00" # 字符串 -> 时间 parsed = datetime.strptime("2026-10-31", "%Y-%m-%d")

实例:

5.shutil方法的基本使用

删除:shutil.retree()

移动:shutil.move()

复制:shutil.copytree()

6.文件I/O与pathlib路径操作

6.1 文件基本操作

打开文件---open(文件路径,打开模式,编码格式)

常用打开模式:r:只读模式,默认值w:写入模式,会覆盖文件内容a:追加模式,不会覆盖文件内容b:二进制模式,用于处理图片、视频等二进制文件+:读写模式,用于读写文件

常用编码格式:utf-8:默认值,用于处理中文gbk: 用于处理中文,不支持处理英文

f = open("文件1", "r", encoding="utf-8") # 读取文件内容 # read() -- 读取文件所有内容 # read(读取字节数) -- 读取指定字节数的内容 text = f.read(2) print(text) # 读取文件内容 # f.read() -- 读取文件所有内容,返回一个字符串 # f.readline() -- 读取文件第一行,返回一个字符串 # f.readlines() -- 读取文件所有行,返回一个列表 # f.read(size) -- 读取指定字节数的内容 # 文件写入操作 # 1-打开文件 # f = open('文件3','w',encoding='utf-8') f = open('文件3', 'a', encoding='utf-8') # 2-写入内容 f.write('hello world') # 3-关闭文件 f.close()

示例:

6.2图片文件复制操作

一般使用分块读写,分块读写是指不一次性把整个文件读入内存,而是按固定大小的"块"(chunk)循环读取、写出。它是处理大文件(大图片、视频、日志)的标准做法。

分块读写内存占用恒定(约等于块大小),1GB 图片也只占几 MB,可逐块处理、显示进度、可中断,可分块发送、断点续传,不会出现大文件复制卡顿、无反馈,网络传输超时。

with open('文件1', 'rb') as f1, open('文件2', 'wb') as f2: chunk = f1.read(1024 * 64) while chunk: f2.write(chunk) current_size += len(chunk) chunk = f1.read(1024 * 64) print()

6.3 os模块的基本使用

os(Operating System,操作系统)是 Python 内置模块,提供与操作系统交互的接口:操作文件、路径、目录,读取环境变量等。它不依赖第三方库,直接import os即可。

6.3.1 os.path常用操作

import os p = "images/头像.jpg" print(os.path.basename(p)) # 头像.jpg 取末级文件名 print(os.path.dirname(p)) # images 取所在目录 print(os.path.splitext(p)) # ('images/头像', '.jpg') 主名与扩展名分开 print(os.path.exists(p)) # True/False 路径是否存在 print(os.path.isfile(p)) # 是否为文件 print(os.path.isdir("images")) # 是否为目录 # 拼接路径,跨平台会自动用正确的分隔符 new_p = os.path.join("images", "备份", "头像.jpg") print(new_p) # images\备份\头像.jpg (Windows) 或 images/备份/头像.jpg (Linux/Mac)

6.3.2 目录与文件操作常用函数

os.mkdir("bak") # 创建单层目录(父目录必须存在) os.makedirs("a/b/c") # 递归创建多层目录 os.listdir("images") # 列出目录下所有文件名 os.remove("头像-复制.jpg") # 删除文件 os.rename("旧名.jpg", "新名.jpg") # 重命名/移动文件 os.getcwd() # 获取当前工作目录(绝对路径) os.chdir("images") # 切换当前工作目录 os.path.getsize("头像.jpg") # 获取文件大小(字节)

注意:

不同系统的路径分隔符不同:Windows 用\(反斜杠),Linux/Mac 用/(正斜杠)。手写"images/" + name在 Linux 没问题,在 Windows 上也可运行但不够规范;而os.path.join会自动选择当前系统正确的分隔符,所以跨平台代码比字符串更安全。

7.lambda函数的基本使用

Lambda 函数(匿名函数)是一种简洁的定义小型函数的方式,核心特点是无需 def 关键字、无需函数名、单行表达式。

基本语法:

lambda 参数列表: 表达式

# 普通函数 def add(x, y): return x + y # lambda 等价写法 add = lambda x, y: x + y print(add(3, 5)) # 8
  • :前面是参数(可省,可多个)
  • :后面是表达式,自动作为返回值

注意事项

  1. 只能写表达式,不能写多行语句、if/else块、for循环。比如lambda x: if x>0: return x是非法的。
  2. 不要滥用:如果逻辑超过一行/比较复杂,应该用def定义,可读性更好。
  3. lambda 本质只是个函数对象,可赋值给变量,也可直接作为参数传入。

8.time模块的基本使用

time是 Python 标准库中用于处理时间与系统时钟的底层模块。核心概念是时间戳(timestamp)——从 1970-01-01 00:00:00(UTC)到现在的秒数。

8.1获取当前时间(时间戳)

import time ts = time.time() # 时间戳(float 秒数) print(ts) # 1779340000.123456 print(type(ts)) # <class 'float'>

8.2程序暂停 ——time.sleep(最常用)

import time print("开始") time.sleep(2) # 阻塞 2 秒 print("结束")

8.3格式化时间 ——strftime

import time # 先把时间戳转成 struct_time,再格式化 loc = time.localtime() s = time.strftime("%Y-%m-%d %H:%M:%S", loc) print(s) # 2026-10-31 14:30:00

9.datetime和time模块的区别

维度datetime模块time模块
设计定位面向对象的数据类型,用于表示和计算日期时间底层系统服务,提供函数式的时间接口和转换
核心形态对象(datetime,date,time,timedelta)函数 + 基础数据结构(浮点数时间戳、struct_time元组)
日期运算支持直观的加减运算(如date + timedelta)不直接支持日期对象的算术运算,通常需手动换算时间戳
时区支持原生支持带时区的对象(tzinfo)时区信息依赖系统环境,处理相对底层
独有功能日期组成部分的提取与替换、ISO 日历操作sleep()延时、perf_counter()高精度计时

如果你需要在程序里表示一个具体的日期、做日期加减、比较两个日期的大小,或者需要处理带时区的跨地域时间,应该用datetime。如果你只是想获取当前时间戳、格式化输出时间字符串、让程序暂停一会儿,或者测量一段代码跑了多久,用time模块更直接。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进