搜索
您的当前位置:首页Python基础之字符编码,文件操作流与函数

Python基础之字符编码,文件操作流与函数

来源:飒榕旅游知识分享网
Python基础之字符编码,⽂件操作流与函数

⼀.字符编码

1.字符编码的发展史

阶段⼀:现代计算机起源于美国,最早诞⽣也是基于英⽂考虑的ASCII

    ASCII:⼀个Bytes代表⼀个字符(英⽂字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表⽰0-2**8-1种变化,即可以表⽰256个字符    ASCII最初只⽤了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英⽂字符/键盘的所有其他字符)    后来为了将拉丁⽂也编码进了ASCII表,将最⾼位也占⽤了

阶段⼆:为了满⾜中⽂,中国⼈定制了GBK  GBK:2Bytes代表⼀个字符

  为了满⾜其他国家,各个国家纷纷定制了⾃⼰的编码

  ⽇本把⽇⽂编到Shift_JIS⾥,韩国把韩⽂编到Euc-kr⾥

阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语⾔混合的⽂本中,显⽰出来会有乱码。  于是产⽣了unicode, 统⼀⽤2Bytes代表⼀个字符, 2**16-1=65535,可代表6万多个字符,因⽽兼容万国语⾔

  但对于通篇都是英⽂的⽂本来说,这种编码⽅式⽆疑是多了⼀倍的存储空间(⼆进制最终都是以电或者磁的⽅式存储到存储介质中的)  于是产⽣了UTF-8,对英⽂字符只⽤1Bytes表⽰,对中⽂字符⽤3Bytes需要强调的⼀点是:

  unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占⽤空间⼤

  utf-8:精准,对不同的字符⽤不同的长度表⽰,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表⽰

2.⽂本编辑器存取⽂件的原理(notepad++,pycharm等)

  打开编辑器就启动了 ⼀个进程,是在内存中的,所以在编辑器编写的内容也都是存放于内存中的,断电后数据丢失,因⽽需要保存到硬盘上。点击保存按钮,就从内存中把数据刷到了硬盘上。在这⼀点上,我们编写⼀个py⽂件(没有执⾏),跟编写其他⽂件没有任何区别,都只是在编写⼀堆字符⽽已。

3.python解释器执⾏py⽂件的原理

  阶段⼀:启动python解释器

  阶段⼆:python解释器此时就是⼀个⽂本编辑器,负责打开⽂件test.py,即从硬盘中读取test.py的内容到内存中

  此时,python解释器会读取test.py的第⼀⾏内容,#coding:utf-8,来决定以什么编码格式来读⼊内存,这⼀⾏就是来设定python解释器这个软件的编码使⽤的编码格式这个编码,

  可以⽤sys.getdefaultencoding()查看,如果不在python⽂件指定头信息#-*-coding:utf-8-*-,那就使⽤默认的  python2中默认使⽤ascii,python3中默认使⽤utf-8

  阶段三:读取已经加载到内存的代码(unicode编码的⼆进制),然后执⾏,执⾏过程中可能会开辟新的内存空间,⽐如x=\"json\"  内存的编码使⽤unicode,不代表内存中全都是unicode编码的⼆进制,

  在程序执⾏之前,内存中确实都是unicode编码的⼆进制,⽐如从⽂件中读取了⼀⾏x=\"json\其中的x,等号,引号,地位都⼀样,都是普通字符⽽已,都是以unicode编码的⼆进制形式存放与内存中的

  但是程序在执⾏过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,⽐如x=\"json\会被python解释器识别为字符串,会申请内存空间来存放\"hello\",然后让x指向该内存地址,此时新申请的该内  存地址保存也是unicode编码的json,如果代码换成x=\"json\".encode('utf-8'),那么新申请的内存空间⾥存放的就是utf-8编码的字符串json了

⼆.⽂件操作

打开⽂件的⽅式有:

r,只读模式(默认)

w,只写模式(不可读;不存在则创建;存在则删除内容;)a,追加模式(可读; 不存在则创建;存在则只追加内容;)\"+\"表⽰可以同时读写某个⽂件

r+,可读写⽂件(可读;可写)w+,写读⽂件(可写;可读)a+,同a\"b\"表⽰处理⼆进制⽂件

rbwb现有如下⽂件:

飞机飞过天空 天空之城落⾬下的黄昏的我们此刻我在异乡的夜⾥感觉着你忽明忽暗

我想回到过去 沉默着欢喜

天空之城在哭泣越来越明亮的你爱情不过是⽣活的屁折磨着我也折磨着你港岛妹妹

你献给我的西班⽛馅饼甜蜜地融化了我天空之城在哭泣港岛妹妹

我们曾拥有的甜蜜的爱情疯狂地撕裂了我天空之城在哭泣

有⼈路过那⾥ 回来告诉我天空之城在哭泣⽆法呼吸的你此刻我在异乡的夜⾥想念着你越来越远

1.\"r\"读取⽂件,并将⽂件输出出来,encoding=\"utf-8\"是将⽂件读取出来以后转换成utf-8格式,在windows下防⽌因为编译格式问题乱码。如果是read(4),4表⽰读的是字符。f = open(\"a.txt\data = f.read()f.closeprint(data)

2.\"w\"写⼊⽂件,将之前的⽂件清空后写⼊。f = open(\"a.txt\f.write(\"炎黄⼦孙\")f.close

3.\"a\"写⼊⽂件,不清空之前的⽂件,将光标移到⽂件的最后,追加写⼊。f = open(\"a.txt\f.write(\"\\n炎黄⼦孙\")f.close()

4.利⽤with语句来帮我们调⽤clese()⽅法,当with执⾏完之后,内部会⾃动关闭并释放⽂件资源。with open(\"a.txt\ print(f.read())

5.seek()内指定的数字代表的是字节数,以⽂件起始位置作为开始。with open(\"a.txt\

f.seek(3) # 默认情况,是以⽂件起始位置作为开始,往后移动3个bytes print(f.readline()) # 读取⽂件第⼀⾏\"\"\"

输出结果:

机飞过天空 天空之城\"\"\"

6.closed判断⽂件是否是关闭状态,返回True或者Falsef = open(\"a.txt\f.close()

print(f.closed)\"\"\"

输出结果:True\"\"\"

7.encoding查看⽂件编码。f = open(\"a.txt\print(f.encoding)\"\"\"

输出结果:utf-8\"\"\"

8.name查看⽂件名

f = open(\"a.txt\print(f.name)\"\"\"

输出结果:a.txt\"\"\"

9.mode指定操作模式,不指定的话默认是r模式(可以改变位置)f = open(\"a.txt\

10. readable判断⽂件是否是r模式打开,返回True或Falsef = open(\"a.txt\print(f.readable()) # 判断⽂件是否是r模式打开\"\"\"

输出结果:True\"\"\"

11. writable判断⽂件是否是w模式打开,返回True或Falsef = open(\"a.txt\print(f.writable()) # 判断⽂件是否是w模式打开\"\"\"

输出结果:True

\"\"\"xt\

12.readline打印⼀⾏,end是不打印换⾏符

f = open(\"a.txt\

print(f.readline(), end=\"\") # readline读取⼀⾏,end是不打印换⾏符print(f.readline(), end=\"\")\"\"\"

输出结果:

飞机飞过天空 天空之城落⾬下的黄昏的我们\"\"\"

13.⽂件修改

import os

read_f = open(\"a.txt\write_f = open(\"b.txt\

for line in read_f.readlines(): # 将a.txt中的⽂件遍历出来

if line.startswith(\"飞机飞过天空天空之城\"): # 判断第⼀句是否是想要修改的内容 line=(\"李志,天空之城\\n\") write_f.write(line)read_f.close()write_f.close()

os.remove(\"a.txt\") # 将a.txt删除

os.rename(\"b.txt\把b.txt改成a.txt 14.⽂件操作,类似于⽇志的实时更新

import time

with open('access.log','r', encoding='utf-8') as f: f.seek(0, 2) while True:

line = f.readline().strip() # 移除字符串头尾指定的字符(默认为空格) if line:

print('新增⼀⾏⽇志:',line) time.sleep(0.5) # 睡眠0.5秒\"\"\"

输出结果:

新增⼀⾏⽇志: 123456 \"\"\"

15.copy图⽚⽂件

with open('1.jpg','rb') as read_f,\\ open('2.jpg','wb') as write_f: data=read_f.read() write_f.write(data)

三.函数

函数介绍:

函数是组织好的,可重复使⽤的,⽤来实现单⼀,或相关联功能的代码段。1.python的内置函数,如:sum,max,min等a = len('hello') # 打印长度b = max([1, 2, 3]) # 求最⼤值print(a)print(b)\"\"\"

输出结果:53\"\"\"

定义函数:

1.⾃定义函数def print_star(): print('*'*6)def print_msg(): print('hello world')print_star()print_msg()print_star()\"\"\"

输出结果:******

hello world******\"\"\"

2.先定义后使⽤。

def foo(): # 指向内存地址 print(\"from foo\")print(foo)\"\"\"

输出结果:

\"\"\"

3.函数的使⽤包含两个阶段:定义阶段和使⽤阶段。语法

def 函数名(参数1, 参数2,...):  \"\"\"⽂档注释\"\"\"  函数体  return 值

4.函数定义的三种形式。

a.⽆参函数:如果函数的功能仅仅执⾏⼀些操作⽽已,就定义成⽆参函数,⽆参函数通常都有返回值。def print_star(): print('*'*6)

b.定义有参函数:函数的执⾏依赖于外部传⼊的参数,有参函数通常都有返回值。def my_max(x,y): res=x if x >y else y return resc.空函数def select(): \"\"\" select \"\"\" pass

调⽤函数:

1.调⽤⽆参函数,定义时⽆参,调⽤时也⽆需传⼊参数。def foo():

print(\"from foo\")foo()\"\"\"

输出结果:from foo\"\"\"

2.调⽤有参函数,定义时有参,调⽤时也必须有参。def bar(name):

print(\"bar=====>\bar(\"json\")\"\"\"

输出结果:

bar=====> json\"\"\"

3. 调⽤函数的表达式形式。def my_max(x, y): res=x if x >y else y return res

res = my_max(12,23)*10print(res)\"\"\"

输出结果:230\"\"\"

4.把函数调⽤,当成另外⼀个函数的参数,求三个数的最⼤值。def my_max(x, y): res=x if x >y else y return res

res = my_max(my_max(9,5), 80)# res = my_max(12,23)*10print(res)\"\"\"

输出结果:80\"\"\"

函数的返回值:

1.不写return,python默认返回Nonedef foo():

print(\"from foo\")res = foo()print(res)\"\"\"

以下三种情况返回都是None:没有 return

return 后边什么都不写return None\"\"\"

2.return⼀个值,函数调⽤返回的结果,也是这个值。def foo():

print(\"from foo\") x = 1 return xres = foo()print(res)\"\"\"

输出结果:1\"\"\"

3.return 值1,值2,值3...返回的是⼀个元组形式。def foo():

print(\"from foo\")

return 1, [1, 2, 3], (1, 2, 3),{}res = foo()print(res)\"\"\"

输出结果:

(1, [1, 2, 3], (1, 2, 3), {})\"\"\"

函数参数:

详细的分函数的参数有五种:

位置参数,关键字参数,默认参数,可变长参数(*args, **kwargs),命名关键字参数。a.位置参数

def foo(x ,y): # 位置形参,必须必须被传值的参数 print(x, y)

foo(1, 2) # 位置实参,与形参⼀⼀对应\"\"\"

输出结果:1 2\"\"\"

b.关键字参数key=value。关键字参数需要注意的问题:1.关键字实参必须在位置实参后边,2.不允许对⼀个形参重复传值。def foo(a ,b, c): print(a ,b, c)foo(c=1,b=2,a=3) \"\"\"

输出结果:3 2 1\"\"\"

c.默认参数

默认参数需要注意的问题:1.默认参数必须在⾮默认参数后,

2.默认参数在定义阶段就已经赋值了,⽽且只能在定义阶段赋值⼀次,3.默认参数的值通常定义成不可变类型。

def register(name,age,sex='male'): #形参:默认参数 print(name,age,sex)register('a', age=18)register('a1', 28)register('a2', 30)register('a3', 29)

register('钢蛋', 20, 'female')

register('钢蛋', sex='female', age=19)\"\"\"

a 18 malea1 28 malea2 30 malea3 29 male钢蛋 20 female钢蛋 19 female\"\"\"

d.可变长参数①*args

def foo(x,y,*args): #*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args print(x,y) print(args)foo(1, 2, 3, 4, 5)\"\"\"1 2(3, 4, 5)\"\"\"

②**kwargs

def foo(x, y, **kwargs): # **会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs print(x, y) print(kwargs)

foo(1,2,a=1,name='egon',age=18)\"\"\"1 2

{'name': 'egon', 'age': 18, 'a': 1}\"\"\"

因篇幅问题不能全部显示,请点此查看更多更全内容

Top