需要了解的文件操作,函数(重要)
需要了解的文件操作
文件的光标移动
文件内光标移动,只有t模式下的read(n),n代表的字符的个数
除此之外在文件中控制光标的移动我们还可以使用seek()函数来进行控制。
# 春游去动物园,hello world
with open('a.txt', 'r', encoding='utf8') as f:
msg = f.read(3) # t模式下,read读取的是字符,所以这里获取到3个字符
print(msg) # 春游去
f.seek(3, 0) # 光标的移动是以字节数,在utf-8中中文是3个字节,字母数字是1个字节,换行符(\n)也是2个字节,将光标移动到第一个字符后
msg = f.read(3) # 此时光标在第一个字符后,所以会打印第一个字符后后面的3个字符
print(msg) # 游去动
with open('a.txt', 'rb') as f:
msg = f.read(6) # 在b模式下,read读取的是字节,中文是3个字节所以会打印出2个中文
print(msg.decode('utf8')) # 春游
f.seek(6, 0) # 将光标移动到到第二个字符后面,以字节为单位进行移动
msg = f.read(6)
print(msg.decode('utf8')) # 去动
'''
需要注意seek方法移动光标时是以字节为单位的,不管在t模式(文本模式)还是在b模式(二进制)下都是一样的。使用seek方法报错时,我们需要注意是不是移动的字节数的问题。
在utf-8中中文是3个字节,字母数字是1个字节,换行符(\n)是2个字节
'''
f.seek(offset,whence)有两个参数:
offset代表控制指针移动的字节数
whence:代表参照什么位置进行移动
whence=0: 参照文件开头(默认的):可以在t模式和b模式下使用
whence=1: 参照当前所在的位置,必须在b模式下使用
whence=2: 参照文件末尾,必须在b模式下使用
'''
需要注意当whencw这个参数为1或2时,文件的操作模式必须是b模式
'''
f.tell()#统计文件的字节数
修改文件的内容
根据现在所学的内容,我们可以使用两种方法来实现文件内容的修改
a.txt:春游去动物园,hello world
第一种:我们将文件内容全部读取出来然后再使用字符串的替换,替换掉我们需要进行替换的内容,然后再重新写入原文件
data = ''
old_word = 'hello'
new_word = 'world'
with open('a.txt', 'r', encoding='utf-8') as f:
data = f.read()
with open('a.txt', 'w', encoding='utf-8') as f:
f.write(data.replace(old_word, new_word))
第二种:先以读的模式打开文件,然后进行一行一行读取,并使用replace方法修改内容,最后一行一行的保存在data变量中(名字随意),然后我们再以写的模式打开原文件,将data写入。
data = ''
old_word = 'hello'
new_word = 'world'
with open('a.txt', 'r', encoding='utf8') as f:
for i in f:
if old_word in i:
i = i.replace(old_word, new_word)
data += i
with open('a.txt','w', encoding='utf8') as f:
f.write(data)
运行后结果为:春游去动物园,world world
(上课讲的)
第三种:使用os模块,以读打开原文件,然后再以写打开一个临时文件,一行一行的读取原文件内容,然后修改好的内容写入临时文件,完成后,使用模块函数删除原文件,将临时文件重命名为原文件的名字。
import os # 模块(后面会学)
with open('a.txt', 'r', encoding='utf-8') as f, \
open('a1.txt', 'w', encoding='utf-8') as f1:
for line in f:
f1.write(line.replace('春', '秋'))
os.remove('a.txt') # 删除文件
os.rename('a1.txt', 'a.txt') # 重命名文件
函数
认识什么是函数
函数专业的说是在开发程序时,需要某块代码多次执行,但是为了提高编写的效率以及代码的重用,把具有独立功能的代码块组织为一个小模块,这就是函数
函数说简单了就是能被重复且具有一定功能的代码块。比如我们之前一直在练习的管理系统,里面的获取用户名和密码这个功能会重复用到,所以我们就可以将这个功能写成一个函数。
函数的结构
(1)def:用于定义函数的关键字
(2)函数名:你所编写的函数的名字
(3)括号:在函数的定义时,后面必须有括号,里面可以放入需要传入的参数
(4)参数:函数外部向函数内部传递的数据
(5)冒号:定义函数也需要有缩进的代码块
(6)函数注释:对代码的解释说明
(7)函数体代码:实现具体功能的代码
(8)return:return后面加上一个返回值,可以将这个值传到函数外面去
函数定义和调用
定义函数的格式:
def 函数名():
代码
Python 使用def 开始函数定义,紧接着是函数名,括号内部为函数的参数,内部为函数的具体功能实现代码
定义一个打印函数
def printinfo():
print('''
春游去动物园
''')
调用函数
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它
调用函数很简单的,通过 函数名() 即可完成调用
printinfo() # 春游去动物园
'''
注意:
每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了
当然了如果函数中执行到了return也会结束函数
'''
# 定义一个函数
def test(a,b):
#2个数求和
print("%d" % (a + b))
test(11,12) # 23
'''
注意:
在我们定义函数时并不会执行函数的代码,只会检测语法错误,所以除了语法错误其他错误都不会进行提示。这时我们写函数的代码时要格外的小心,尽量别写错,毕竟有可能问题在哪都找不到。
定义函数的过程不会执行函数体代码 只会检测语法
def index():
xsadasd 定义的时候不会报错
def index1():
if 语法错误定义的时候就会报错
'''
函数的参数
定义时小括号中的参数,用来接收参数用的,称为 “形参”
调用时小括号中的参数,用来传递给函数用的,称为 “实参”
此处引用别人的例子:
def add2num(a, b):
c = a+b
print c
add2num(110, 22) # 调用带有参数的函数时,需要在小括号中,传递数据
![](https://s1.ax1x.com/2022/03/15/bvIN2F.gif)
函数的返回值
返回值:运行函数时有时会得到一个结果,这个结果就是返回值
def addto(a, b):
c = a + b
return c # c就是返回值
d = addto(10, 20) # 需要用一个变量来接返回值
print(d) # 30
今日作业
尝试着使用函数写注册登录
(在昨日作业基础上修改)
def login():
username = input('请输入你的用户名: ').strip()
password = input('请输入你的密码: ').strip()
with open('a.txt', 'rb') as f1:
for i in f1:
if username == i.decode('utf8').split('|')[0]:
print('账号已经存在')
break
else:
with open('a.txt', 'ab') as f1:
add = username + '|' + password + '|\n'
f1.write(add.encode('utf8'))
def register():
username = input('请输入你的用户名: ').strip()
password = input('请输入你的密码: ').strip()
with open('a.txt', 'rb') as f1:
for i in f1:
if username == i.decode('utf8').split('|')[0] and password == i.decode('utf8').split('|')[1]:
print('登入成功')
break
else:
print('账号或密码错误')
try:
f = open('a.txt', 'rb')
f.close()
except FileNotFoundError:
f = open('a.txt', 'wb')
f.close()
finally:
while True:
print(
"""
1.注册
2.登入
3.退出
""")
choice = input('请输入指令: ').strip()
if choice == '1':
login()
elif choice == '2':
register()
elif choice == '3':
break
else:
print('请输入正确的指令')