函数
函数的概念
函数是带名字的代码块,用于完成具体的任务,可重复使用。
Python中的函数必须先定义后使用,Python提供了许多内建函数,比如print()。也可以自己创建函数,这被叫做用户自定义函数。
函数的定义
语法
Python 定义函数使用 def 关键字,一般格式如下:
python
def 函数名 (参数列表) :
函数体
[return]
定义一个函数的规则
- 函数代码块以def关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串---用于存放函数说明。用三个引号括起来,单引号和双引号都可以。
- 函数参数后面以冒号结束。
- 函数体开始缩进。
- return 表达式 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
函数名
函数名需要遵循标识符的命名规则。一般是一个动词,第一个单词小写,其他每个单词的首字母大写。
参数
函数在完成某个功能时,可能需要一些数据,在定义函数时指定函数参数来接收这些数据。如果有多个参数,参数之间使用逗号分隔。函数也可以没有参数,但是小括弧不能省略。
函数体
调用函数时执行的代码,可包含函数说明文档与返回值。
返回值
有些函数在执行的时候,需要有返回值给调用者,通过return关键字进行返回,返回到函数调用的位置。
函数的抽取以及调用
函数定义好之后,通过函数名()对函数进行调用。
注意:
- 函数必须先定义再调用
- 函数在定义的时候只是告诉解释器我定义了一个这样的函数,可以完成某些功能,但是这个时候函数还没有执行,需要调用函数后,才会执行。
使用函数的好处
- 使程序变得更简短而清晰
- 可以提高程序开发的效率
- 提高了代码的重用性
- 便于程序分工协作开发
- 便于代码的集中管理
- 有利于程序维护
函数的参数
形参和实参
- 在定义函数时,指定的参数称为形式参数,简称为形参(函数的提供者)
在调用函数时,给函数传递的参数称为实际参数,简称为实参(函数的调用者)
- 在定义函数时,形参没有分配存储空间,也没有值,相当于一个占位符;
在调用函数时, 会在栈区中给函数分配存储空间, 然后给形参/局部变量分配存储空间,传递的是实际的数据
- 当函数执行结束,函数所占的栈空间会被释放,函数的形参/局部变量也会被释放
函数的参数传递
1)在 python 中,类型属于对象,变量是没有类型的:
python
a=10
a="helloworld"
以上代码中,10是数字类型," helloworld " 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向数字类型对象,也可以是指向 String 类型对象。
2)引用的概念
在 Python 中,变量和数据是分开存储的,数据保存在内存中的一个位置,变量中保存着数据在内存中的地址,变量中记录数据的地址,就叫做引用。
使用id()函数可以查看变量中保存数据所在的内存地址
注意:如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用,变量不再对之前的数据引用,变量改为对新赋值的数据引用,变量的名字类似于便签纸贴在数据上。
3)可变(mutable)与不可变(immutable)类型对象
在Python常见的类型中,数字类型、string、tuple是不可更改的对象,而list、set、dict等则是可以修改的对象。
- 不可变类型
变量赋值 a=500 后再赋值 a=1000,这里实际是新生成一个 int 值对象 1000,再让 a 指向它,而500被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型
变量赋值 la=1,2,3,4 后再赋值 la2=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
4)Python函数的参数传递
- 不可变类型
类似c++的值传递,如整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在fun(a)内部修改a的值,只是修改另一个复制的对象,不会影响 a 本身。
- 可变类型
类似c++的引用传递,如列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
Python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
案例: Python函数传不可变对象实例
python
def changeInt(a) :
print("函数体中未改变前a的内存地址",id(a))
a = 10
print("函数体中改变后a的内存地址",id(a))
b = 2
changeInt(b)
print(b)
print("函数外b的内存地址",id(b))
# 输出结果:
# 函数体中未改变前a的内存地址 140711474555352
# 函数体中改变后a的内存地址 140711474555608
# 2
# 函数外b的内存地址 140711474555352
说明:实例中有 int 对象 2,指向它的变量是b,在传递给 changeInt 函数时,按传值的方式复制了变量 b,a 和 b 都指向了同一个 int 对象,函数外b的内存地址和未改变前a的地址是相同的。在 a=10 时,则新生成一个 int 值对象 10,并让 a 指向它。这个时候内存地址也发生了改变。
案例:Python函数传可变对象实例
python
def changeList(myList) :
myList[1] = 50
print("函数内的值",myList)
print("函数内列表的内存",id(myList))
mlist = [1,2,3]
changeList(mlist)
print("函数外的值",mlist)
print("函数外列表的内存",id(mlist))
# 输出结果:
# 函数内的值 [1, 50, 3]
# 函数内列表的内存 1546427570560
# 函数外的值 [1, 50, 3]
# 函数外列表的内存 1546427570560
说明:
可变对象在函数里修改了参数,那么在函数外面,这个原始的参数也被改变了。
通过内存地址的输出,我们可以看出来,是在原有的列表对象上进行的修改。
注意:var1 *= 2 与 var1 = var1 * 2 的区别:
- var1 *= 2使用原地址。
- var1 = var1 * 2开辟了新的空间。
python
def multiply2(var1):
print("函数内var1 id:", id(var1))
var1 *= 2
print("var1 *= 2后,函数内var1 id:", id(var1))
var1 = var1 * 2
print("var1 = var1 * 2后,函数内var1 id:", id(var1))
list1 = [1, 2, 3]
print("list1 id:", id(list1))
multiply2(list1)
# 输出结果:
# list1 id: 2302584035712
# 函数内var1 id: 2302584035712
# var1 *= 2后,函数内var1 id: 2302584035712
# var1 = var1 * 2后,函数内var1 id: 2302584033664
函数可使用的参数形式
必须参数
调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于位置把每个相应位置的实参和形参相关联,调用时的数量必须和声明时的一样。
按位置传参
python
def func(a, b, c):
print(a, b, c)
func(1, 2, 3) # 1 2 3
可以看到,1传给了a,2传给了b,3传给了c。
关键字参数
函数调用使用关键字参数来确定每个变量传入的参数值,使用关键字参数允许函数调用时参数的顺序与声明时不一致。
python
def printInfo(name,age) :
print("姓名:",name)
print("年龄:",age)
# Python解释器可以通过age和name这样的关键字去和形参进行匹配
printInfo(name = "zhangsan",age = 18)
printInfo(age = 18,name = "zhangsan")
默认值参数
定义函数时,可给每个形参指定默认值。在调用函数时,给形参提供了实参则使用指定的实参值,否则使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。注意:非默认参数必须放在默认参数之前。
python
def printInfo(name,age = 20) :
print("姓名:",name)
print("年龄:",age)
printInfo("zhangsan")
printInfo("lisi",30)
printInfo(age = 40,name = "wangwu")
不定长参数1个星
参数的个数是不确定的。使用一个*+参数名,默认使用的tuple接收
语法:
python
def 函数名([普通参数,] *var_args_tuple):
函数体
案例:
python
def printInfo(num,*vartuple):
print(num)
print(vartuple)
printInfo(70,60,50)
print("-" * 20)
# 如果不定长的参数后面还有参数,必须通过关键字参数传参
def printInfo1(num1,*vartuple,num) :
print(num)
print(num1)
print(vartuple)
printInfo1(10,20,num = 40)
print("-" * 20)
# 如果没有给不定长的参数传参,那么得到的是空元组
printInfo1(70,num = 60)
注意:
- 加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
- 如果形参中出现了不定长参数,那么在调用函数的时候,先通过位置进行必须参数的匹配,然后不定长参数后面的参数必须通过关键字参数匹配
- 如果不定长的参数后面还有参数,必须通过关键字参数传参
不定长参数-带2个星
参数的个数是不确定的。使用一个**+参数名,默认使用的dict接收,基本语法如下:
python
def 函数名([普通参数,] **var_args_dict ):
函数体
注意:加了两个星号 ** 的参数会以字典的形式导入,后面就不能再有其他参数了,普通参数形式也是键值对,会与此时混淆
python
def printInfo(num,**vardict):
print(num)
print(vardict)
# return
printInfo(10,key1 = 20,key2 = 30)
printInfo(10,a = 20,b = 30)
解包传参
若函数的形参是定长参数,可以通过 * 和 ** 对列表、元组、字典等解包传参。
python
def func(a, b, c):
return a + b + c
tuple11 = (1, 2, 3)
print(func(*tuple11))
# 字典中key的名称和参数名必须一致
dict1 = {"a": 1, "b": 2, "c": 3}
print(func(**dict1))
强制使用位置参数或关键字参数
/ 前的参数必须使用位置传参,* 后的参数必须用关键字传参。
python
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
f(1, 2, 3, d=4, e=5, f=6)
防止函数修改列表
有时要函数对列表进行处理,又不希望函数修改原列表,可以使用 copy.deepcopy()。
python
import copy
def multiply2(var1):
var1[3].append(400)
print("函数内处理后:", var1)
list1 = [1, 2, 3, [100, 200, 300]]
print("函数外处理前:", list1)
multiply2(copy.deepcopy(list1))
print("函数外处理后:", list1)

函数说明文档
编写了函数说明文档后,可以通过 help(函数名) 获取函数说明文档。
python
def adult(age=18):
"""根据年龄判断是否成年"""
result = "未成年"[age >= 18 :]
return result
help(adult)

PyCharm中将鼠标悬停在函数名上方也可以看到函数说明文档。

返回值
在程序开发中,有时候希望一个函数执行结束后,告诉调用者一个结果,以便调用者针对具体的结果做后续的处理。返回值就是函数完成工作后,给调用者的一个结果
- 在函数中使用 return 关键字可以返回结果 ,并结束正在执行的函数
- 如果return后面跟表达式,在结束函数的同时向调用方返回一个表达式。
- 如果仅仅是return关键字,后面没有加内容,函数执行返回调用方None。
- 调用函数一方,可以使用变量来接收函数的返回结果
不带表达式的 return 语句,返回 None。
python
def f(a, b, c):
pass
return
print(f(1, 2, 3)) # None
函数中如果没有 return 语句,在函数运行结束后也会返回 None。
python
def f(a, b, c):
pass
print(f(1, 2, 3)) # None
用变量接收返回结果
python
def add(num1,num2) :
'''求两个数的和'''
sum1 = num1 + num2
return sum1
res = add(10,20)
print("两个数的和为:" ,res)
return 语句可以返回多个值,多个值会放在一个元组中。
python
def f(a, b, c):
return a, b, c, [a, b, c]
print(f(1, 2, 3)) # (1, 2, 3, [1, 2, 3])
函数嵌套调用
在一个函数中调用另一个函数,当内层函数执行完之后才会继续执行外层函数。
python
def function_A():
print("\t函数 A 开始执行")
print("\t函数 A 执行中...")
print("\t函数 A 结束执行")
def function_B():
print("函数 B 开始执行")
print("函数 B 执行中...")
function_A()
print("函数 B 执行中...")
print("函数 B 结束执行")
function_B()
输出结果:
函数 B 开始执行
函数 B 执行中...
函数 A 开始执行
函数 A 执行中...
函数 A 结束执行
函数 B 执行中...
函数 B 结束执行
变量的作用域
Python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。变量的作用域决定了哪一部分程序可以访问哪个变量,Python的作用域一共有4种,分别是:
- L (Local) 局部作用域
- E (Enclosing)嵌套作用域 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内建作用域
以 L --> E --> G -->B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。以下案例演示各种作用域类型。
python
a = int(2.9) # 内建作用域 (Python本身提供的,在所有位置都可以访问)
b = 0 # 全局作用域
def outer():
c = 1 # 嵌套作用域
def inner():
d = 2 #局部作用域
print(d,c,b,a)
return inner
in_func=outer()
in_func()
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:
python
# 分支,循环不会引入新的作用域
num = 2
if num > 1:
msg = "helloWorld"
print(msg)
def test():
msg_test = "welcome"
print(msg_test)
实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。
如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:
从报错的信息上看,说明了 msg_test未定义,无法使用,因为它是局部变量,只有在函数内可以使用。
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
python
sum = 0 # 这是一个全局变量
def add(num1,num2) :
sum = num1 + num2 # 这是一个局部变量
print("函数内局部变量的值:",sum,id(sum))
return sum
add(10,20)
print(num1) # num1访问不到
print("函数外全局变量:",sum,id(sum))

global关键字
使用global修改全局变量
定义了一个全局变量,如何在函数内对其进行修改?
直接在函数内修改
通过var1 += 200修改。会报错
当你在函数内部对一个变量进行赋值操作时,Python 默认会把这个变量当作局部变量,即便全局作用域中已经存在同名变量。
python
var1 = 100
def function_a():
var1 += 200 # 将var1当做局部变量处理,+=得先定义变量
function_a() # 报错
② 通过var1 = 200修改。全局变量var1的值并没被修改,仍是100。我们只是在function_a函数中新定义了一个局部变量var1并将其赋值为200。
python
var1 = 100
def function_a():
var1 = 200
print("var1:", var1)
print(var1) # 100
function_a() # var1: 200
print(var1) # 100
在函数内使用 global 声明全局变量
函数内使用 global 声明全局变量后,可以修改全局变量。
python
def function_a():
global var1
var1 = 200
print("var1:", var1)
var1 = 100
print(var1) # 100
function_a() # var1: 200
print(var1) # 200
修改可变类型的全局变量
当全局变量为可变类型时,函数内不使用 global 声明,也可以对其进行修改。
python
def function_a():
list1[0] = -1000
print("list1:", list1)
list1 = [1, 2, 3]
print(list1) # [1, 2, 3]
function_a() # list1: [-1000, 2, 3]
print(list1) # [-1000, 2, 3]
在函数中不使用 global 声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
不可变类型的全局变量其指向的数据不能修改,所以不使用 global 无法修改全局变量。
可变类型的全局变量其指向的数据可以修改,所以不使用 global 也可修改全局变量。
nonlocal关键字
nonlocal 也用作内部作用域修改外部作用域的变量的场景,不过此时外部作用域不是全局作用域而是嵌套作用域。
python
def function_outer():
var1 = 1
print(var1)
def function_inner():
nonlocal var1
var1 = 200
function_inner()
print(var1)
function_outer() # var1: 1 -> 200
递归
概念
递归一种是逻辑思想,将一个大工作分为逐渐减小的小工作,只不过在程序中,就是依靠函数嵌套这个特性来实现
本质
递归调用就是在函数体中又调用了函数本身.
在定义递归函数的时候,主要确定两点
- 确定它们之间的规律
- 确定递归结束的条件
递归案例 **求一个整数n的阶乘!**
python
'''
5! = 5 * 4 * 3 * 2 *1
'''
# 不使用递归的方式
def get_factorial(num):
res = 1 # 用于存放积
for n in range(1,num+1):
res *= n
return res
print(get_factorial(5))
print("-"*20)
def get_factorial2(n):
return n * get_factorial2(n - 1) if n > 1 else 1
print(get_factorial2(5)) # 120
递归执行流程分析

匿名函数
语法
Python使用 lambda 来定义匿名函数,所谓匿名,指其不用 def 的标准形式定义函数。
lambda 参数列表: 表达式
- lambda 只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块,所以仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
使用普通函数传参
def operator(a, b):
return a + b
def function(a, b, operator):
return operator(a, b)
print(function(1, 2, operator))
使用匿名函数传参
def function(a, b, operator):
return operator(a, b)
print(function(1, 2, lambda x, y: x + y))
匿名函数作为内置函数的参数
可以将匿名函数与常用的内置参数搭配使用。
sorted()
有三名学生的姓名和年龄,按年龄排序。
student_list = {"name": "zhang3", "age": 36}, {"name": "li4", "age": 14}, {"name": "wang5", "age": 27}
print(sorted(student_list, key=lambda x: x"age"))
map()
map() 函数对序列中元素逐一处理。
map_result = map(lambda x: x * x, 0, 1, 3, 7, 9)
print(list(map_result)) # 0, 1, 9, 49, 81
filter()
filter() 函数对序列中元素过滤。
filter_result = filter(lambda x: x >= 0, -0, -1, -3, 7, 9)
print(list(filter_result)) # 0, 7, 9
reduce()
reduce() 函数对序列中元素进行累积。
from functools import reduce
reduce_result = reduce(lambda x, y: x * y, 1, 2, 3, 4, 5)
print(reduce_result) # 120
函数的注释(了解)
Python 3.x 引入了函数注释,以增强函数的注释功能
普通的自定义函数:
def dog(name, age, species):
return (name, age, species)
添加了注释的自定义函数:
def dog(name:str, age:(1, 99), species:'狗狗的品种') -> tuple:
return (name, age, species)
print(dog.annotations)
如上,可以使用:对参数逐个进行注释,注释内容可以是任何形式,比如参数的类型、作用、取值范围等等,返回值使用->标注,所有的注释都会保存至函数的属性。
查看这些注释可以通过自定义函数的特殊属性__annotations__获取,结果会以字典的形式返回,另外,使用函数注释并不影响默认参数的使用
{'name': <class 'str'>, 'age': (1, 99), 'species': '狗狗的品种', 'return': <class 'tuple'>}
文件操作
基本概念
在计算机中,文件是存储在磁盘上的数据集合。文件可以包含各种类型的数据,如文本、图像、音频、视频或程序代码。
文件系统通过文件名和文件路径来定位和管理文件。文件名通常包含文件的名称和扩展名,扩展名用于表示文件的类型(例如 .txt 表示文本文件,.jpg 表示图像文件)。文件路径可以是绝对路径(从文件系统的根目录开始)或相对路径(相对于当前工作目录)。
在编写程序的时候,数据是以二进制的形式存储在内存的,将数据写到磁盘文件的过程称之为持久化。
文件的分类
纯文本文件
有统一的编码,可以被看做存储在磁盘上的长字符串。
纯文本文件编码格式常见的有ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16等。
二进制文件
没有统一的字符编码,直接由0与1组成。
如图片文件(jpg、png),视频文件(avi)等。
文件的路径
相对路径
从当前位置到指定位置的路径。
如:./hello_world.py
./代表当前路径。../代表上一级路径。
绝对路径
从根目录到指定位置的路径。
如:E: / Hello /hello.py
文件的打开与关闭
打开文件
使用 open() 打开或创建文件,该方法执行完毕之后返回的是一个file对象。
常用形式
open(文件名, 模式)
f = open("test.txt", "w")
|------------|-------------------------------|
| 模式 | 说明 |
| r | 读写方式:只读,文件若不存在会报错。默认此模式 |
| w | 读写方式:写入,写入前清空原有数据。文件不存在会创建文件 |
| a | 读写方式:追加写入,在原有数据后追加,文件不存在会创建文件 |
| x | 读写方式:创建新文件并写入,文件若已存在会报错 |
| b | 编码方式:以二进制打开。一般用于非文本文件如图片等 |
| t | 编码方式:以文本模式打开,默认此模式 |
| + | 能读能写 |
完整形式
python
open(
file, # 文件路径
mode="r", # 文件打开模式
buffering=-1, # 缓冲
encoding=None, # 文本编码方式,一般用utf8
errors=None, # 报错级别
newline=None, # 区分换行符
closefd=True, # 传入的file参数类型
opener=None, # 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符
)
关闭文件
f.close()
文件读写
写数据
python
# 打开文件
f = open("test.txt", "w")
# 写入数据
f.write("hello world\n")
f.write("nihao python\n")
# 关闭文件
f.close()
读数据
read(size) 可以从文件中读取数据,size 表示要从文件中读取的数据的长度(单位是字节),如果没有传入 size 则读取文件中所有的数据。
python
# 打开文件
f = open("test.txt", "rt")
# 读取文件所有数据
print(f.read())
# 关闭文件
f.close()
print("-"*20)
f = open("test.txt", "rt")
# 读取文件5个字节数据
print(f.read(5))
print(f.read(8))
f.close()
readline(size) 可以从文件中读取整行数据,也可以通过 size 设置读取数据的长度。
python
f = open("test.txt", "rt")
print(f.readline())
print(f.readline(1))
print(f.readline(1))
f.close()
readlines(size) 读取所有行并返回列表,若给定 size>0,返回总和大约为 size 字节的行, 实际读取值可能比 size 大。
python
f = open("test.txt", "r", encoding="utf-8")
print(f.readlines())
f.close()
常用函数
|------------------------------------|---------------------------------------------------------------------------------------------------------|
| 函数 | 说明 |
| file.seek(offset,from) | 移动偏移量并返回新的绝对位置。 offset:移动的字节数,如果是负数表示从倒数第几位开始。 from:从哪个位置开始移动;0为开头,1为当前位置,2为末尾。from不为0时需使用'b'二进制模式打开文件。 |
| file.tell() | 返回当前偏移量 |
| file.truncate(size) | 从开头开始截断文件为size个字符,无size表示从当前位置截断。windows系统下的换行大小2个字符 |
| file.writelines(seq) | 将序列中字符串写入文件,需要自己加入换行符 |
| file.readable() | 如果可以读取文件则返回True |
| file.writeable() | 如果可以写入文件则返回True |
| file.seekable() | 如果文件支持随机访问则返回True |
| os.rename(old,new) | 重命名文件 |
| os.remove(file) | 删除文件 |
| os.mkdir(dir) | 创建目录,不支持递归创建 |
| os.makedirs(dir) | 递归创建目录 |
| os.getcwd() | 获取当前路径 |
| os.chdir(dir) | 进入指定目录 |
| os.listdir(dir) | 获取目录下文件和目录列表 |
| os.rmdir(dir) | 删除空目录 |
| os.removedirs(dir) | 递归删除空目录 |
| os.path.abspath(path) | 将相对路径转换为绝对路径 |
| os.path.basename(path) | 获取路径中的文件名部分 |
| os.path.dirname(path) | 获取路径中的目录部分 |
| os.path.join(*paths) | 拼接多个路径,自动处理路径分隔符 |
| os.path.split(path) | 将路径分割为目录和文件名的元组 |
| os.path.splitext(path) | 将路径分割为文件名和扩展名的元组 |
| os.path.exists(path) | 判断路径是否存在 |
| os.path.isfile(path) | 判断路径是否为文件 |
| os.path.isdir(path) | 判断路径是否为目录 |
| os.path.getsize(path) | 获取文件的大小,以字节为单位 |
| os.path.getatime(path) | 获取文件的最后访问时间 |
| os.path.getmtime(path) | 获取文件的最后修改时间 |
os.walk()递归遍历目录
用法
python
# 返回一个3元组(dirpath文件夹路径, dirnames文件夹名字, filenames文件名)
os.walk(
top, # 根目录
topdown=True, # 可选,默认为True:自顶向下,False:自底向上
onerror=None, # 可选,是一个函数
followlinks=False, # 可选,设置为True则通过软链接访问目录
)
案例:递归遍历当前路径下所有目录和文件
python
import os
for root, dirs, files in os.walk(os.getcwd()):
print("当前路径:", root)
print("目录:", dirs)
print("文件:", files)
print()
案例:文件拷贝
python
# source_file : 源文件路径
# dest_file: 目的地文件路径
def copyFile(source_file_path,dest_file__path):
# 打开源文件
source_file = open(source_file_path, 'rb')
# 读取源文件中的内容
content = source_file.read()
# 打开目的地文件
dest_file = open(dest_file__path, 'wb')
# 将读取到的数据写入到目的地
dest_file.write(content)
# 关闭源文件
source_file.close()
# 关闭目的地文件
dest_file.close()
copyFile("D:/mv.png","E:/mv.png")
优化:这种方式可以不用读取整个文件,减小内存压力
python
# source_file : 源文件路径
# dest_file: 目的地文件路径
def copyFile(source_file_path,dest_file__path):
# 打开源文件
source_file = open(source_file_path, 'rb')
# 打开目的地文件
dest_file = open(dest_file__path, 'wb')
# 读取源文件中的内容
content = source_file.read(1024)
while content:
# 将读取到的数据写入到目的地
dest_file.write(content)
# 继续从源文件读取数据
content = source_file.read(1024)
# 关闭源文件
# 关闭目的地文件
dest_file.close()
copyFile("D:/mv.png","E:/mv.png")