疫情环境下的网络学习笔记 python 3.17

3.17

上节课复习

  1. x模式,只写模式,不存在则创建,存在则报错

  2. b 模式:以bytes为单位读写,可以操作所有文件,一定不能指定encoding

  3. 操作:f.read() 得到二进制,python针对二进制封装得到bytes类型,显示的都是bytes

  4. 要想在b模式得到字符,要手动解码编码

    res.decode('utf-8')
    
  5. 看到bytes类型,就把他当作二进制

    bytes转二进制:

    • b’英文字符’ 字符串前面加b
    • 字符串编码之后的结果:’上’.encode(‘utf-8’)
    • b 模式下打开文件,f.read 读出内容
  6. readline(),readlines(),read(n)

    防止一次读取文件过大占用过多内存,指定长度读取或循环读取文件

    while True:
    	line = f.read(1024)
    	if len(line) == 0:
    		break
    
  7. f.seek(n,mode)

    • 0 模式:相对文件开头
    • 1 模式:相对于当前指针位置
    • 2 模式:相对于文件末尾

今日内容

  1. tail -f access.log
  2. 文件修改的两种方式
  3. 函数
  4. 函数参数

正课

tail-f

Linux中命令,动态查看文件变化,用于纪录日志

需求:读末尾新加的数据,需先将指针跳到文件末尾:f.seek(0,2)

import time
with open('access.log',mode = 'rt',encoding = 'utf-8') as f:
	f.seek(0,2)
	f.readline()
	while True:
		line = f.readline()  # 从最末尾,新加入内容之前的位置,往后读
		if len(line) == 0:
			time.sleep(0.3)  # 睡0.3秒,防止一直死循环
		else:
			print(line)

注意只有在 b 模式下才搭配使用 seek ,因为b 模式以字节为单位编写,移动指针才有意义

文件修改的两种方式

我们在改文件时,在源文件里新增,新增后面的部分都往后平移。但是在硬盘上实际上这样修改,会把后面同等长度的字节覆盖。硬盘上的数据没有改 这一说,都是用新的覆盖老的

在文本编辑器上修改,保存后实际上是使用内存上的内容覆盖回硬盘

方式1 文本编辑器

with open('c.txt','r',encoding = 'utf-8') as f:
	res = f.read
	修改
with open('c.txt','w',encoding = 'utf-8') as g:
	g.write(res)
  • 占用内存大,要把整个文件放进内存

  • 不占硬盘空间

方式2

import os
with open('c.txt','r',encoding = 'utf-8') as f,
	open('.c.txt.swap','wt',encoding = 'utf-8') as f1:
	for line in f:
		f1.write(line.replace(''))
os.remove('c.txt')
os.rename('.c.txt.swap','c.txt')

创造一个新文件,删除旧文件,将新文件名命名为旧文件

  • 占用硬盘空间,不占用内存空间

函数

什么是函数

  • 相当于具备某一功能的工具
  • 函数的使用必须遵循一个原则:先定义后使用

为什么要用函数

  1. 代码冗余,程序组织结构不清晰,可读性差
  2. 可维护性,可扩展性差

如何用函数

先定义

定义函数发生的事情:

  • 申请内存空间,保存函数体代码
  • 将上输内存地址绑定给函数名
  • 定义函数不会执行函数体代码,但会检测其语法

调用函数发生的事情:print(函数名),得到函数体的内存地址

  • 通过函数名找到函数的内存地址
  • 通过加括号就是在触发函数体代码的执行

函数的嵌套,在定义的时候不管其中嵌套的函数有没有被定义,只检测语法,此时调用的函数没有被定义也不会报错。在真正执行该函数的时候,才会去看这个被嵌套的函数有无被定义

def foo():
    bar()  # 此时只检测语法,不管有没有定义
    print('from foo')
def bar():  # bar=函数的内存地址
    print('from bar')
foo()

定义的语法

def 函数名(参数1,参数2,...):
    '''文档描述'''
	函数体
	return 值
  • 必须要有:def,函数名,括号,冒号,函数体
  • 可以没有:参数,返回,文档描述
  • 函数名的命名规则与变量名一样,更多地应该命名成动词
  1. 定义形式1 无参函数

    def func():
    	pass
    # 定义无参函数
    # 调用
    func()
    
  2. 定义形式2 有参函数

    def func(x,y):
    	print(x,y)
    # 定义有参函数
    # 调用的时候,也要传入参数
    func(1,2)
    
    
  3. 定义形式3 空函数

    函数体代码为pass,...,不执行任何操作

三种定义形式各有其用处

函数相当于一个工厂,函数体相当于加工的模板流程,参数相当于加工的原材料,返回值相当于工厂的产品

各个工厂干的活不一样,有些工厂必须要原材料才能运行,有些工厂不需要原材料,有工厂不产生产品

  1. 无参 / 有参 数函数的应用场景:写死 / 不写死功能
  2. 空函数的应用场景:构思代码的时候,编程写框架的时候

调用函数

  1. 语句的形式,只加括号调用,不做其他操作

    func(x,y)
    
    
  2. 表达式形式

    res = func(x,y)  # 赋值表达式
    func(x,y) * 10  # 数学表达式
    
    
  3. 函数调用可以当作参数

    func(func(1,2),y)  # 实际上传入的参数是func(1,2)的返回值和y
    
    

函数返回值

函数经过运算产生的产品

return 是函数结束的标志,函数体代码一旦运行到 return,会立刻终止运行,并且会将return 后的值当作本次运行的结果返回:

  1. 返回 none:没有 return 或着return 后面什么也没有

  2. 返回一个值:

    return value

  3. 返回多个值:

    用逗号分隔开多个值,会被 return 转成元组返回

    return 10,'aa',[1,2]
    # 得到(10,'aa',[1,2])
    
    
原文地址:https://www.cnblogs.com/telecasterfanclub/p/12512114.html