深入理解Python中的字符编码、文件处理和函数

来源:互联网 发布:疯狂java讲义百度云 编辑:程序博客网 时间:2024/05/16 09:43

博客核心内容:


1、Python基础之字符编码的介绍
2、Python中文件处理的介绍
3、Python中函数的介绍
4、 File.readlines(sizehint) 函数


一、Python基础之字符编码的介绍

在Python当中,字符编码的问题贯穿整个学习的始终,下面详细的介绍一下字符编码的相关知识,主要介绍内容:
①文本编辑器(nodepad++、word、pycharm)存取文件的原理.
②Python解释器执行py文件的原理.
③字符编码的相关概念.
④字符编码的分类.


1、文本编辑器(nodepad++、word、pycharm)存取文件的原理
打开文本编辑器相当于启动了一个应用进程,是在内存中的,所以在编辑器中编写的内容也都是存放在内存中的,为了防止断电后数据丢失,我们需要将数据由内存保存到磁盘中去,点击保存按钮,就从内存中将数据刷到了硬盘上。
所以当我们打开pycharm这个编辑器编辑文件(没有执行),跟其他编辑器编写文件没有任何区别,都只是在编辑一堆字符而已。
如果所示:pycharm、nodepad++对应的应用进程。
这里写图片描述


2、Python解释器执行py文件的原理,例如D:\Python34>python.exe C:\Users\zhangmingyang\Desktop\2.py。
①:python解释器启动,此时就相当于启动了一个文本编辑器,
②:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中,
③:python解释器解释执行刚刚加载到内存中test.py的代码。

D:\Python34>python.exe  C:\Users\zhangmingyang\Desktop\2.py亲你好,请输入指定的序号选择对应的服务1、查看之前的购物记录2、购买商品q、退出当前购物提供

在这里面插入一句话:
各种高级语言Java、Python本质上就是一种软件,这些软件有的叫做解释器,有的叫做虚拟机,下面我们看到的这个文件夹实际上就是一个Python软件,即Python解释器。
这里写图片描述
语言分为两种:C语言和其他高级语言。
其他高级语言会先转化成字节码 ,然后在转化成机器码,最后在交给计算机去执行,而C语言是直接转化成机器码,然后在交给计算机去执行。
总结:
python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与普通文本编辑器是一样的,与普通文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容


3、字符编码的相关概念
由于在上一篇我的博客里对字符编码的概念已经做了介绍,这个就不在介绍了,贴一下相关链接:
http://blog.csdn.net/a2011480169/article/details/71435114


4、字符编码的分类(我个人认为这个知识点及其重要)
字符编码的分类:ASCII编码、Unicode编码、UTF-8编码、GBK编码。
ASCII编码:这种编码格式是用8位即一个字节来表示一个字符,所以ASCII编码最多只能表示出256个字符。
如:A这个字符对应的ASCII编码格式为0100 0001。
缺点:ASCII编码无法将世界上的各种文字和符号全部表示出来,主要用于表示英文字符、键盘上的所有其它字符和拉丁文。
Unicode编码:这种编码格式规定至少用两个字节(即16位)来表示一个字符,解决了所有字符和符号的编码问题,可以兼容万国语言。
优缺点:简单粗暴,所有字符都是2字节,优点是字符->数字的转换速度快,缺点是占用空间大,对于用传统ASCII编码就可以表示的字符来说(比如通篇都是英文的文本),这种编码格式多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)。
UTF-8编码:这种编码格式是对Unicode编码的压缩和优化,将所有的字符和符号进行分类:对英文字符只用1个字节表示,对中文字符用3个字节表示。
优点:精准,对不同种类的字符用不同长度的字节来表示,节省空间,缺点:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的字节才能够准确表示。
总结:
内存中使用的编码是Unicode编码(快),用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)
,硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。
gbk:这种编码格式是用16位即两个字节来表示一个汉字字符,但是不能解决汉字和英文以外的字符的编码问题,是专门针对中文的编码格式。
优点:对于同一个汉字,使用gbk编码在底层是以两个字节来进行的表示,而utf-8却是用三个字节来进行表示。
缺点:利用gbk这种编码只能解决汉字以及基本英文字符的存储问题。
大致列表如下:
这里写图片描述
编码与解码的过程图:
encode(内存到硬盘的存储过程):将内存中的unicode编码编码成硬盘中的utf-8(else)编码,这个过程就是encode。
decode(硬盘到内存的解码过程):将硬盘中的utf-8(else)编码解码成内存中的unicode编码,这个过程就是decode。
文件中的内容在没有执行之前,文件中的内容在内存当中统一以unicode编码格式保存的,但是执行过程当中可能转化成其他格式的编码。
这里写图片描述
核心总结:
无论是何种编辑器,要防止文件中的内容出现乱码,核心法则就是,文件中的内容以什么编码格式保存的,就以什么编码方式打开这个文件。
PyCharm这个软件的好处就在于文件中的内容以哪种编码格式打开,文件中的内容默认就以哪种编码格式保存。
部分代码示例:

#!/usr/bin/python# -*- coding:utf-8 -*-    #指定读文件的编码格式x = "李杰"#unicode---->encode---->utf-8(字节码)print(x.encode("utf-8"))   #字节码#unicode---->encode---->gbk(字节码)print(x.encode("gbk"))     #字节码user_name = "李杰"user_2 = user_name.encode("utf-8")print(user_2)print(user_2.decode())  #decodeprint(user_name.encode("utf-8"))print(user_name.encode("gbk"))

运行结果:

b'\xe6\x9d\x8e\xe6\x9d\xb0'b'\xc0\xee\xbd\xdc'b'\xe6\x9d\x8e\xe6\x9d\xb0'李杰b'\xe6\x9d\x8e\xe6\x9d\xb0'b'\xc0\xee\xbd\xdc'
一、Python中文件处理的介绍

我将Python中对文件处理常用的方法总结如下:

在文件处理当中,只有read默认是以字符为单位,其他方法均已字节为单位.def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):    file表示文件的名称,可以是绝对路径,也可以是相对路径.    mode表示打开文件的方式,r表示读,w表示写,a表示追加.    encoding表示已哪种编码格式读取文件中的内容,如果不指定,默认使用当前平台的编码,对于    Windows操作系统来说为gbk编码.    open()成功返回一个文件对象后,后续对该文件的操作都通过这个“句柄”实现。打开文件的三种方式:r : 以r的方式打开整个文件,若文件不存在,则直接报错w : 以w的方式打开整个文件,若文件存在则先清空文件的内容(但是并不删除文件),若文件不存在则先创建这个文件。注意:在以w的方式打开整个文件的过程中,只有在第一次打开文件的时候才会先清空整个文件的内容,在整个操作的过程中并不会写一次清除一次。r和w代表以文本的方式读,并以文本的方式写。a : 以追加的方式打开整个文件,若文件不存在则先创建这个文件,若文件存在则只追加内容。"+" 表示可以同时读写某个文件    r+, 读写【可读,可写】,文件不存在会报错的    w+, 写读【可读,可写】, 清空文件内容,然后以读写方式打开文件。    a+ ,写读【可读,可写】"b"表示已字节流的方式操作相应的文件,当以"b"的方式操作文件的时候,处理数据的基本单位是字节(二进制),而不再是字符。    rb,  以二进制的方式读写某个文件          (直接将文件在硬盘中对应的bytes读取到内存当中)    wb,  以二进制的方式向某个文件中写入内容。(直接将文件对应的bytes写到硬盘当中)def close(self, *args, **kwargs):         程序结束之后要注意关闭流从而释放与该流相关的所有系统资源.def read(self, *args, **kwargs):         read()从文件中读取指定个数的字符(r模式)或者字节(rb模式),如果没有给定参数size(默认-1)或为负数,则一直读至末尾,获取整个文件的内容。def write(self, *args, **kwargs):         向文件中写入字符串,并返回写入字符的个数,注意:要自己添加相应的换行符。def writelines(seq)            向文件中写入一个字符串列表,注意:seq中的每个元素必须是字符串类型.def readable(self):        判断文件的打开方式是否是可读的,如果是则返回True.def writable(self, *args, **kwargs):         判断文件的打开方式是否是可写的,如果是则返回True.def seek(self,offset,whence=0):     控制文件光标位置移动的字节数,    whence=0代表文件的开始位置.    whence=1代表光标所处的当前位置    whence=2代表文件的结束位置.    注意:seek处理数据的单位为字节。def tell(self, *args, **kwargs):         当前文件中光标所处的位置.def readline(self, *args, **kwargs):         读取一行文本,并随后将光标转移至下一行的起始偏移量。def readlines(self, hint=-1):        读取文件所有行文本的内容,并以列表的形式进行返回。def truncate(self, *args, **kwargs):     截取文件的内容,其中结果只保留前n个字节的内容。文件操作的其他功能:  文件的修改:1、读源文件的内容,然后一行一行的向新文件中写.2、通过os模块将源文件给删除.3、将新文件重命名为源文件的名字。

示例程序1:文件修改的示例程序

#!/usr/bin/python# -*- coding:utf-8 -*-import os#以读的方式打开一个文件fr1 = open("aa.txt",mode="r",encoding="utf-8")#以写的方式打开一个文件fr2 = open("bb.txt",mode="w",encoding="utf-8")#读取源文件的内容,并将文件中的内容一行一行的写的新的文件当中for line in fr1.readlines():    if line.strip() == "11111111":        line = "66668888\n"    fr2.write(line)fr1.close()fr2.close()#删除源文件os.remove("aa.txt")#将目标文件重名为源文件os.rename("bb.txt","aa.txt")with可以同时处理多个文件:with open("aa.txt",encoding="utf-8") as fr1 , open("bb.txt",encoding="utf-8") as fr2:     print(fr1.read())     print(fr2.read())

示例程序2:“b”字节流(二进制)的方式操作文件

#!/usr/bin/python# -*- coding:utf-8 -*-with open("aa.txt","rb") as fr1:     #以二进制串的方式读取某个文件,并通过utf-8格式的编码进行解码     #fr1.read()相当于将文件中的二进制串直接拷贝到内存当中     data = fr1.read().decode(encoding="utf-8")     print(data)with open("aa.txt","rb") as fr, \    open("bb.txt","wb") as fw:    data = fr.read()    fw.write(data)with open("cc.txt","wb") as fw2:    #将李杰这两个汉字以utf-8这种编码格式的二进制串写到计算机的硬盘当中    fw2.write("李杰".encode("utf-8"))

示例程序3:模拟tail -F word.txt查看文件结尾最新的变化

#!/usr/bin/python# -*- coding:utf-8 -*-with open("aa.txt","r",encoding="utf-8") as fr1:    #在文件的结束文件向右偏移0个字节,直接到文件的末尾    fr1.seek(0,2)    while True:        line = fr1.readline().strip()        if line:            print(line)
三、Python中函数的介绍(上)

我自己总结了一下Python中函数的一些重要知识:

Python中函数的参数详细可以分为5种:1、位置参数def fun(x,y,z) :x、y、z为位置参数,特点:必须被传值的参数,并且实际参数的数值与形式参数的数值一一对应。2、关键字参数(类似于Scala中的带名参数)def fun(x,y,z) ==>  fun(z=3,x=1,y=2) 特点:关键字的参数必须在位置参数的后面,并且不能重复对一个形式参数赋值。3、默认参数def fun(name,age,sex="man") : sex为默认参数, 特点:函数调用的时候默认参数可以不用被赋值,默认参数必须跟在非默认参数的后面;默认参数在定义阶段就已经赋值了,而且只在定义阶段赋值一次;默认参数的数值通常定义为不可变类型。4、可变长参数(*args,**kwargs)def fun(*args,**kwargs):在调用函数时,实际参数的长度是可以改变的。特点:*args     *会把溢出的按位置定义的实参都接收,并以元组的形式赋值给args。      1,2,3,4 <====> *(1,2,3,4),*对应位置参数来看待。      **kwargs  **会把溢出的按关键字定义的实参都接收,并以字典的形式赋值给kwargs。      **对应的就是关键字。      #fun(*[A,B,C]) 等价于  fun(A,B,C)      #fun(x=1,y=2)  等价于  **{x:1,y:2}5、命名关键字参数def foo(name,age,*,sex='male',height): (了解一下即可)特点:*后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值.注意:各种参数可以混合使用,但是使用的场景为0,因为各类参数之间会相互影响,取消相互的意义。

实例程序1:可变长参数的示例

#!/usr/bin/python# -*- coding:utf-8 -*-def fun(*args):    sum = 0    for num in args:        sum += num    return sumsum = fun(10,20,30)print(sum)

示例程序2:可变长参数的使用

#!/usr/bin/python# -*- coding:utf-8 -*-def fun(x,y,**args):    print(x,y,args)fun(10,20,name="Alex",age=15,times=3)

示例程序3:可变长参数的理解转换(很重要)

def wrapper(*args,**kwargs):      print(args)         #args=(1,2,3)      print(kwargs)       #kwargs={a:1,b:2}      foo(*args,**kwargs) #foo(*(1,2,3),**{a:1,b:2}) #foo(1,2,3,a=1,b=2)wrapper(1,2,3,a=1,b=2)
4、 File.readlines(sizehint) 函数

转载网址:http://blog.csdn.net/holy_phoenix/article/details/1616994
OK,总结到这里,如有问题,欢迎留言指正!

原创粉丝点击