文件读写操作
在 Linux 系统中万物皆文件,所以我们不可避免的要和文件打交道,我们会常常对文件进行读和写的操作。
cat /etc/password # 读文件
vim /etc/password # 读写文件
echo test > /tmp/abc.txt # 覆盖写文件
echo text >> /tmp/abc.txt # 追加写文件
而以上内容我们都是对文本文件进行读写,计算机中也存在对二进制文件的读写操作,那用 Python 如何实现呢?
文件的打开方法—open 内建函数
不管是读文件还是写文件,我们第一步都是要将文件打开。
作为打开文件之门的“钥匙”,内建函数 open() 提供了初始化输入/输出(I/O)操作的通用接口,成功打开文件后时候会返回一个文件对象,否则引发一个错误。
参数介绍
file_name:表示我们要打开文件的路径
mode:以怎样的方式打开文件
文件模式 | 操 作 |
---|---|
r | 以读方式打开(文件不存在则报错) |
w | 以写方式打开(文件存在则清空,不存在则创建) |
a | 以追加模式打开 |
b | 以二进制模式打开 |
file_object:文件操作对象,我们后续对文件的所有读写操作都需要通过这个对象,而不是直接操作文件中的数据。
文件读操作
要使用文本文件中的信息,首先需要将信息读取到内存中。为此,我们可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。
read 方法 —— 读取文件
-
open
函数的第一个参数是要打开的文件名(文件名区分大小写)- 如果文件 存在,返回 文件操作对象
- 如果文件 不存在,会 抛出异常
-
read
方法可以一次性 读入 并 返回 文件的 所有内容 -
close
方法负责 关闭文件- 如果 忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问
-
注意:
read
方法执行后,会把 文件指针 移动到 文件的末尾
[root@python day03]# cat 01_read_file.py
#目标:读取/etc/hosts文件的内容
#1.打开文件( 打开冰箱门)
myfile = open('/etc/hosts','r')
#第一个参数是文件路径,第二个参数是读写方式'r'代表读,'w'代表写
#2.读/写文件(把大象放进冰箱)
char3 = myfile.read(3) #读取文件中的前三个字符
print('char3:',char3) #打印内容char3: 127
char6 = myfile.read(6)
print('char6:',char6) #.0.0.1
chars = myfile.read() #读取剩余全部内容
print('chars:',chars)
#3.关闭文件(关上冰箱门)
myfile.close() #一个打开的文件只能关闭一次
[root@python day03]# python3 01_read_file.py
char3: 127
char6: .0.0.1
chars: localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
readline 方法 —— 按行读取
read
方法默认会把文件的 所有内容 一次性读取到内存- 如果文件太大,对内存的占用会非常严重
readline
方法可以一次读取一行内容- 方法执行后,会把 文件指针 移动到下一行,准备再次读取
[root@python day03]# cat 03_file_tarval_lines.py
#此示例示意使用文件的readline方法每次读取一行数据
#目标:读取/etc/passwd文件前三行
fr = open('/etc/passwd','r')
line1 = fr.readline()
print('第一行:',line1,end='') #打印完之后,不打印新的换行符
line1 = fr.readline()
print('第二行:',line1,end='')
line1 = fr.readline()
print('第三行:',line1,end='')
fr.close()
[root@python day03]# python3 03_file_tarval_lines.py
第一行: root:x:0:0:root:/root:/bin/bash
第二行: bin:x:1:1:bin:/bin:/sbin/nologin
第三行: daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@python day03]#
使用readline遍历文件
[root@python day03]# cat 02_readline.py
#此示例示意使用文件的readline方法遍历文件中每一行
#目标:读取/etc/passwd文件所有行
fr = open('/etc/passwd','r')
while True:
aline = fr.readline()
if aline == '': #判断是否到达文件尾部
break
print(aline,end='')
fr.close()
[root@python day03]# python3 02_readline.py
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
polkitd:x:998:995:User for polkitd:/:/sbin/nologin
unbound:x:997:994:Unbound DNS resolver:/etc/unbound:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
chrony:x:996:993::/var/lib/chrony:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
对文件流对象,进行遍历可以读取每一行数据:
[root@python day03]# cat 04_file_fr.py
#打开文件 fr变量绑定的是文件流对象,文件流对象是可迭代对象
# 对文件流对象,进行遍历可以读取每一行数据
fr = open('/etc/passwd','r')
for aline in fr:
print(aline,end='')
fr.close()
[root@python day03]# python3 04_file_fr.py
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
polkitd:x:998:995:User for polkitd:/:/sbin/nologin
unbound:x:997:994:Unbound DNS resolver:/etc/unbound:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
chrony:x:996:993::/var/lib/chrony:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
readlines 方法
readlines()
方法读取所有(剩余的)行然后把它们作为一个 字符串列表 返回
图例
- 如果需要逐行处理文件,可以结合 for 循环迭代文件
- 迭代文件的方法与处理其他序列类型的数据类似
[root@python day03]# cat 05_.py
#内容,形成列表并返回
#目标:/etc/hosts 文件
fr = open('/etc/hosts','r')
contents = fr.readlines() #contents内容
fr.close()
print('内容',contents) #['aaa\n','bbb\n']
[root@python day03]# python3 05_.py
内容 ['127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4\n', '::1 localhost localhost.localdomain localhost6 localhost6.localdomain6\n']
文件写操作
write 方法 —— 写文件
-
write() 内建方法功能与
read()
和readline()
相反- 它把含有 文本数据 或 二进制数据 的内容写入到文件中去
[root@python day03]# cat 06_file_write.py
#此示例示意使用write方法向文件内写入数据
#目标:创建一个文件 my_mimi.txt,向内部写入银行卡帐号和密码
#1.打开文件
fw = open('my_mimi.txt','w') #’w'以写的模式打开
#2.读写文件
fw.write('工商银行帐号:') #写只能写入字符串
fw.write('62222090909090090090') #不能写入数字
fw.write('\n') #写入换行符号
fw.write('密码:123456')
fw.write('\n')
#3.关闭文件
fw.close()
[root@python day03]# python3 06_file_write.py
[root@python day03]# cat my_mimi.txt
工商银行帐号:62222090909090090090
密码:123456
[root@python day03]#
writelines 方法
- 和
readlines()
一样,writelines()
方法是针对 列表 的操作 - 它接受一个 字符串列表 作为参数,将他们写入文件
- 行结束符并不会被自动加入,所以如果需要的话,必须再调用 writelines() 前给每行结尾加上行结束符
总结:
with 子句 (用来关闭文件的,释放资源的)
- with语句 是用来简化代码的
- 在将打开文件的操作放在 with 语句中,代码块结束后,文件将自动关闭
- 读写文件的逻辑没有变化,变得只是 写法
[root@python day03]# cat 08_file_with.py
#此示例示意使用with语句来自动关闭文件
#1.不使用with的情况
fw = open('my_mimi3.txt','w')
fw.write('account:666677778888\n')
fw.close()
#使用with的方法
with open('my_mimi3.txt','w') as fw:
fw.write('account:999999999999999\n')
[root@python day03]# python3 08_file_with.py
[root@python day03]# cat my_mimi3.txt
account:666677778888
[root@python day03]# cat my_mimi3.txt
account:999999999999999
[root@python day03]# cat 09_cp.py
#此示例实现cp命令,将/usr/bin/ls 复制到 /tmp目录下
fr = open('/usr/bin/ls','rb') #b-->binary(二进制操作文件)
fw = open('/tmp/myls','wb')
#复制内容
content = fr.read()
fw.write(content)
fw.close()
fr.close()
[root@python day03]# python3 09_cp.py
[root@python day03]# /tmp/myls
-bash: /tmp/myls: Permission denied
函数
快速体验
-
所谓函数,就是把 具有独立功能的代码块 组织为一个小模块,在需要的时候 调用
-
:函数的使用包含两个步骤:
- 定义函数 —— 封装 独立的功能
- 调用函数 —— 享受 封装 的成果
函数的创建与调用
创建函数
函数用 def
语句创建,语法如下:
[root@python day03]# cat 10_def.py
#示例函数的定义和调用
#1.定义一个函数
def washing_machine():
print('注水')
print('洗衣机')
print('甩干')
#2.函数调用
washing_machine()
washing_machine()
[root@python day03]# python3 10_def.py
注水
洗衣机
甩干
注水
洗衣机
甩干
标题行由 def
关键字,函数的名字,以及参数的集合(如果有的话)组成
def
子句的剩余部分包括了一个可选的文档字串,和必需的函数体
函数名称 的命名应该 符合 标识符的命名规则
- 可以由 字母、下划线 和 数字 组成
- 不能以数字开头
- 不能与关键字重名
注意:函数要先定义再调用,顺序不可以变
函数的参数
形参和实参
- 形参:定义 函数时,小括号中的参数,是用来接收参数用的,在函数内部 作为变量使用
- 实参:调用 函数时,小括号中的参数,是用来把数据传递到 函数内部 用的
传递参数
在函数名的后面的小括号内部填写 参数
多个参数之间使用 ,
分隔
调用函数时,实参的个数需要与形参个数一致,实参将依次传递给形参
[root@python day03]# cat 10_def.py
def washing_machine(something):
print('注水')
print('洗衣粉')
print('洗'+ something)
print('甩干')
#2.函数调用
washing_machine("衣服")
#washing_machine()
def myadd(num1,num2,num3,num4):
result = num1+num2+num3+num4
print('result',result)
myadd(10,20,30,40)
[root@python day03]# python3 10_def.py
注水
洗衣粉
洗衣服
甩干
result 100
默认参数(缺省参数)
默认参数就是声明了 默认值 的参数,因为给参数赋予了默认值,所以在函数调用时,不向该参数传入值也是允许的
注意事项: 1.如果没有手动给形参赋值,那么就用默认值 2.传递的实际参数优先级比默认参数要高 3.定义函数时,有默认值的参数一定放在没有默认值参数的后面
[root@python day03]# cat 11_default.py
#示例函数的缺省参数的用法
def myadd(num1,num2,num3=0,num4=0):
result = num1+num2+num3+num4
print('result',result)
myadd(10,20,30,40)
myadd(1,2,3)
[root@python day03]# python3 11_default.py
result 100
result 6
[root@python day03]#
函数的返回值
- 在程序开发中,有时候,会希望 一个函数执行结束后,告诉调用者一个结果,以便调用者针对具体的结果做后续的处理
- 返回值 是函数 完成工作后,最后 给调用者的 一个结果
- 在函数中使用
return
关键字可以返回结果 - 调用函数一方,可以 使用变量 来 接收 函数的返回结果
注意:
return
表示返回,表示方法执行结束,后续的代码都不会被执行
[root@python day03]# cat 14_return.py
#示例return语句的用法
def washing_machine(something):
print('注水')
print('洗' + something)
#return '干净的' + something
print('防水')
print('甩干')
return '完成' + something
value = washing_machine('袜子')
print('value:',value) #None
[root@python day03]# python3 14_return.py
注水
洗袜子
防水
甩干
value: 完成袜子
练习:斐波那契数列函数
斐波那契数列函数
- 将斐波那契数列代码改为函数
- 数列长度由用户指定
- 要求把结果用 return 返回