文件修改及函数定义

1. 文件的高级应用

1.1 可读可写

r+: 在后面追加,即可读又可写(尽量不要使用)

with open('test.py','r+',encoding='utf8') as fr:
    data = fr.read()
    print(fr.writable())
    fr.write('x = 10')
    print(data)

w+: 清空文件的功能是w提供的,w+更不要使用

with open('test.py','w+',encoding='utf8') as fr:
    # print(fr.writable())
    # fr.write('x = 10')
    data = fr.read()
    print(data)

a+:有追加的功能,a的指针在末尾,a+功能也没有

with open('test.py','a+',encoding='utf8') as fr:
    fr.seek(1,0)
    data = fr.read()  # 指针在末尾
    print(data)

    fr.write('x = 10')
    fr.flush()

1.2 指针的应用(移动指针)

文件的内置方法:seek, tell, read(n), truncate

1.2.1 seek

0相当于文件头开始;1相当于当前文件所在位置;2相当于文件末尾

with open('test.py','r',encoding='utf8') as fr:
    fr.seek(1)  # 1表示位移1位,默认从文件头开始
    fr.seek(1,0)  # 1表示偏移1位,0表示从头开始
    fr.seek(2, 1)  # 1表示偏移1位,0表示从头开始
    fr.seek(0, 2)  # 0表示偏移0位,2表示文件末开始,把指针移到文件末
    print(fr.read())

1.2.2 tell

每次统计都是从文件开头到当前指针所在位置

with open('test.py', 'r', encoding='utf8') as fr:
    fr.seek(2,0)
    print(fr.tell())

1.2.3 read(n)

读几个字符/几个字节

with open('test.py', 'r', encoding='utf8') as fr:
    print(fr.read(5))

1.2.4 truncate

truncate(n)是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate()要在r+或a或a+等模式下测试效果。它的参照物永远是文件头。并且truncate()不加参数,相当于清空文件。

with open('test.py', 'a', encoding='utf8') as fr:
    fr.truncate(2) # 把2个字符后面的东西全清空

2. 文件修改的两种方式

文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式。

2.1 方式一

将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)。

import os
import time
with open('test.py','r',encoding='utf8') as fr,\
        open('test_swap.py','w',encoding='utf8') as fw:
    data = fr.read()  # 全部读入内存,如果文件很大,会很卡
    data = data.replace('下','小') # 在内存中完成修改
    fw.write(data) # 新文件一次性写入原文件内容

time.sleep(5)
os.remove('test.py')  # 删除文件
os.rename('test_swap.py','test.py') # 重命名文件

2.2 方式二

将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件。

import os
with open('test.py', 'r', encoding='utf8') as fr, \
        open('test_swap.py', 'w', encoding='utf8') as fw:
    for i in fr:
        i = i.replace('小','大')
        fw.write(i) 

os.remove('test.py')  # 删除文件
os.rename('test_swap.py','test.py') # 重命名文件

总而言之,修改文件内容的思路为:以读的方式打开原文件,以写的方式打开一个新的文件,把原文件的内容进行修改,然后写入新文件,之后利用os模块的方法,把原文件删除,重命名新文件为原文件名,达到以假乱真的目的。

3. 函数的定义

在程序中,函数就是具备某一功能的工具,事先将工具准备好就是函数的定义,遇到应用场景拿来就用就是函数的调用。

定义函数的方式:

'''
def 函数名():  # 定义阶段
    """函数注释写在这里"""  # 函数相当于工具,注释相当于工具的说明书
    <代码块>

# 使用  # 调用阶段
函数名()
'''
## 定义阶段不执行函数体代码,只检测语法错误(牢记)
def func():
    '''func函数的注释'''
    # todo:未来写一个函数
    pass
print(func.__doc__)  # 记住 # 打印注释

eg:

def register():
    '''注册函数'''
    username = input('请输入你的用户名:')
    pwd = input('请输入你的密码:')

    with open('user_info.txt','a',encoding='utf8') as fa:
        fa.write(f'{username}:{pwd}')

def login():
    '''登录函数'''
    username = input('请输入你的用户名:')
    pwd = input('请输入你的密码:')

    with open('user_info.txt', 'r', encoding='utf8') as fr:
        data = fr.read()
        user_list = data.split('|')
        print(user_list)
        user_info = f'{username}:{pwd}'
        if user_info in user_list:
            print('登录成功')
        else:
            print('登陆失败')
            
register() # 调用
login()    # 调用

4. 函数的三种定义方式

4.1 无参函数

在函数阶段括号内没有参数,称为无参函数。需要注意的是:定义时无参,意味着调用时也无需传入参数。

def add():  工具可以单独使用
    '''无参函数'''
    x = input('num1:')
    y = input('num2:')

    print(int(x) + int(y))

add()

4.2 有参函数

在函数定义阶段括号内有参数,称为有参函数。需要注意的是:定义时有参,意味着调用时也必须传入参数。

def add(x,y):  # 这个工具不能单独使用,必须要加个配件,才能使用
    '''有参函数'''
    print(int(x) + int(y))

x = input('num1:')
y = input('num2:')
add(x,y)

4.3 空函数

空函数:定义了函数,啥都没有

当你只知道你需要实现某个功能,但不知道该如何用代码实现时,你可以暂时写个空函数,然后先实现其他的功能。

def func():  # 只知道工具叫什么名字,但不知道如何造这个工具
    pass

5. 函数的调用

def add(x,y):
    print(x+y)

add(10,20)  # 函数的调用

6. 函数的返回值

函数的返回值:函数内部代码经过一些列逻辑处理获得的结果。

def add(x,y):
    # 逻辑
    print(x + y)
    # return x+y  # 函数的返回值;终止函数(跳出函数)
    print(1)

print(2)

res = add(1,2)   # 默认返回None
print(res)

return是一个函数结束的标志,函数内可以有多个return,只要执行到return,函数就会执行。

def add(x,y):
    # return (x,y,x+y)  # return可以返回任意数据类型
    return x,y,x + y  # return可以返回任意数据类型,不加括号返回多个值时,默认用元祖的形式返回

x,y,z = add(1,2)
print(x,y,z)

7. 函数的参数

7.1 形参

形参:定义阶段才有形参,形式参数,啥也没用,只是占个位置,具有描述意义,本质就是变量名

7.2 实参

实参: 调用阶段才有实参,实际的参数,具有具体的值

def add(num1,num2): # 形参
    """有参函数"""
    print(int(num1) + int(num2))

add(1,2)  # 实参

7.3 位置参数

在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参

在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参

def add(num1,num2): # 形参
    """有参函数"""
    print(num1)
    print(num2)
    print(int(num1) + int(num2))

add(1,2)  # 实参
def shopping(name = 'nick'): # 形参经常会引用同一个值
    goods_dict = {1:'特斯拉',2:'奔驰',3:'劳斯莱斯'}
    print(f'恭喜你{name},得到{goods_dict[1]}一个')

shopping('bob')

两个位置形参,就必须得要两个位置实参对应,从左到右一一对应

默认形参:不需要传参,可以使用默认值;传参就使用你传的值,默认形参必须放到位置形参后面

7.4 关键字实参

按照形参名给定具体的值,可以打破位置形参必须得一一对应传值的规定,位置实参必须在关键字实参之前,即在调用函数时,按照key=value的形式为指定的参数传值

def shopping(x,name = 'nick'): # 形参经常会引用同一个值
    goods_dict = {1:'特斯拉',2:'奔驰',3:'劳斯莱斯'}
    print(f'恭喜你{name},得到{goods_dict[x]}一个')

shopping(1,name='bob')

注意

  1. 可以混用位置实参和关键字实参,但是位置实参必须在关键字实参的左边。
  2. 可以混用位置实参和关键字实参,但不能对一个形参重复赋值。
  3. 函数的参数尽量不要超过3个
  4. 需要用的时候用,一般用位置形参+位置实参
posted @ 2019-08-08 16:20  PLPLPL  阅读(294)  评论(0编辑  收藏  举报
// 目录