文件的光标、修改,函数寄基本介绍

今日内容总结

昨日内容的小补充

      with上下文管理是可以一次性打开多个文件的。代码示例:

  # 昨日作业1优化 source_file_path为拷贝文件路径 target_file_path为拷贝文件到的路径
  with open(r'%s' % source_file_path, 'rb') as f1, open(r'%s' % target_file_path, 'wb') as f2:
      for line in f1:
          f2.write(line)
# 以只读的方式打开打开拷贝文件路径,以只写的方式打开拷贝文件到的路径

文件内光标的移动

      光标移动的介绍

      在之前的文件内置方法中提到,read()是读取文件内所有内容,执行完该操作后,文件指针会移动到文件末尾,这个时候我们再想read()就做不到了。这是因为第一次read()的时候,光标是在文件最开始一直移动读取,直到最后的。因为光标已经到最后了,你接下来再读取,它也不会移动,也就取不到值了。所以,我们就有了接下来的方法。代码示例:

  # a.txt的内容为 Jason NB 鸡哥NB Jason NB 鸡哥NB Jason NB 鸡哥NB
  with open(r'a.txt', 'r', encoding='utf8') as f:
      print(f.read(3))  # Jas
      print(f.read(3))  # on 

  # read在文本模式下 括号内的数字表示的是读取指定的字符个数
  with open(r'a.txt', 'rb') as f:
      print(f.read(3).decode('utf8'))  # Jas
      print(f.read(1).decode('utf8'))  # o

  # read在二进制模式下 括号内的数字表示的是读取指定的字节数

      控制光标的移动

      seek方法可以控制光标的移动,在文本模式下移动的单位也是字节数。其中,seek方法可以这样表示:seek(offset,whence)。offset表示控制移动的字节数,whence表示控制模式。接下来是对三个模式的基本使用代码示例:

  # 0模式的使用
  with open('a.txt',mode='rt',encoding='utf-8') as f:
      f.seek(3,0)     # 参照文件开头移动了3个字节
      print(f.tell()) # 查看当前文件光标距离文件开头的位置,输出结果为3
      print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
      # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败
      # 相对于文件开头(让光标先移动到文件开头),支持文本模式和二进制模式

  # 1模式的使用
  with open('a.txt',mode='rb') as f:
      f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
      print(f.tell()) # 输出结果为:3
      f.seek(4,1)     # 从当前位置往后移动4个字节,而此时的当前位置为3
      print(f.tell()) # 输出结果为:7
      # 相对于当前位置(让光标先停留在当前位置),只支持二进制模式

  # 2.模式的使用
  with open('a.txt',mode='rb') as f:
      f.seek(0,2)     # 参照文件末尾移动0个字节, 即直接跳到文件末尾
      print(f.tell()) # 输出结果为:9
      f.seek(-3,2)     # 参照文件末尾往前移动了3个字节
      print(f.read().decode('utf-8')) # 输出结果为:好
      # 相对于文件结尾(让光标先移动到文件末尾),只支持二进制模式

  # 实时检测文件内是否有新增的内容并打印出来(没有太多的实际意义)
    with open('a.txt', mode='rb') as f:
        f.seek(0, 2)
        while True:
            line = f.readline()
            if len(line) == 0:
                # 没有内容
                pass
            else:
                print(line.decode('utf-8'), end='')

文件的修改

      硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容,内存中的数据是可以修改的。而今天鸡哥的课前闲聊中,提到了硬盘上的数据的两个状态,占有态和自由态。

      我们删除数据其实就是将数据原来的位置标记成自由态,之后如果有新的数据进来了并且落到了自由态位置那么直接覆盖。

      上述主要是让我们了解数据恢复的原理,以及隐私保护,修改文件数据的原理等。而这里我们修改文件的方式分为两种。代码示例:


  # 第一种 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件 优点是在文件修改过程中同一份数据只有一份。缺点是会过多的占用内存
  with open('a.txt',mode='rt',encoding='utf-8') as f:
      data=f.read()

  with open('a.txt',mode='wt',encoding='utf-8') as f:
      f.write(data.replace('Jason','NB'))
  # 第二种 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名 优点是不会占用过多的内存。缺点是在文件修改过程中同一份数据存了两份
  import os  # 模块(后面会学)

  with open('a.txt', 'r', encoding='utf-8') as read_f, \
          open('.a.txt.swap', 'w', encoding='utf-8') as wrife_f:
      for line in read_f:
          wrife_f.write(line.replace('jason', 'jerry'))
  os.remove('a.txt')  # 删除文件
  os.rename('.a.txt.swap', 'b.txt')  # 重命名文件

函数简介

      函数,其实相当于是工具,创建函数,就是创建工具,函数的使用,就是对工具的使用。在之前的学习中,我们会发现,有些代码,我们是需要重复使用的,而为了不每次需要这串代码,我们都重新敲一遍。所以函数的使用,就出现了。我们将这串代码设置为函数,定义给一个函数名(与变量名一样),这样我们在需要使用这串代码时,调用该函数方法就可以了。调用函数需要使用函数名加括号。代码示例:


  # 以代码的方式实现len(在不使用len方法的情况下统计元素个数)
  a = [1, 2, 3, 4]
  print(len(a))  # 4
  n = 0
  for i in a:
      n += 1
  print(n)  # 4

  def m_len():
      n = 0
      for i in a:
          n += 1
      print(n)  
    m_len()  # 4

  # 虽然上述方式实现了不借助与len完成元素个数的统计,但是需要反复的编写相同的代码,也就是说我们只能统计变量a的元素个数

  # 同时我们发现了,以前使用的数据类型的内置方法,其实也叫数据类型的内置函数。

函数的语法结构


def 函数名(参数1, 参数2...):
    '''函数的注释'''
    函数体代码
    return  # 返回值

      def def就是定义函数的关键字。函数名,类似于变量名 指代函数体代码,命名与变量名一致。括号,在定义函数的时候,函数名后面一定是括号,括号内可以写参数,参数,似于使用函数的时候 给函数内部传递的数据,可以不写,或者单个、多个。冒号,定义函数的函数体代码时需要有缩进的。函数的注释,用于解释函数的主要功能、使用方法等说明性文字。函数体代码,函数的核心功能 也是我们将来编写的核心。return,后面跟什么 那么执行完函数之后就会返回什么。

      值得注意的是,定义函数的过程不会执行函数体代码 只会检测语法。也就是说,我们只要不执行,写错了也不会报错,但是要符合语法。语法错误的话,就会报错,代码示例:

def index():
    xsadasd  # 定义的时候不会报错
def index1():
    if  # 语法错误定义的时候就会报错

今日作业、


# 1.登录注册的重复练习
data_list = ['jason|123', ]
j = 0
while j < 3:
    print('输入1注册,输入2登录,输入3退出')
    num = input('请输入功能>>>:').strip()
    a = 1
    if num == '1':
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        for i in data_list:
            if username == i.split('|')[0]:
                print('该用户已存在')
                break
        else:
            data = f'{username}|{password}'
            data_list.append(data)
    elif num == '2':
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        for i in data_list:
            if username == i.split('|')[0]:
                if password == i.split('|')[1]:
                    print('登录成功')
                    a = 0
                    break
                else:
                    print('密码错误')
                    j += 1
        else:
            j += 1
            if a == 1:
                print('用户名不存在')

    else:
        print('退出成功')
        break

# 2.尝试使用函数写登录注册

data_list = ['jason|123', ]


def register():
    for i in data_list:
        if username == i.split('|')[0]:
            print('该用户已存在')
            break
    else:
        data = f'{username}|{password}'
        data_list.append(data)

def login():
    a = 1
    for i in data_list:
        if username == i.split('|')[0]:
            if password == i.split('|')[1]:
                print('登录成功')
                a = 0
                break
            else:
                print('密码错误')
    else:
        if a == 1:
            print('用户名不存在')

while True:
    print('输入1注册,输入2登录,输入3退出')
    num = input('请输入功能>>>:').strip()
    if num == '1':
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        register()
    elif num == '2':
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        login()
    else:
        print('退出成功')
        break
posted @ 2022-03-15 19:07  くうはくの白  阅读(85)  评论(0)    收藏  举报