Python数据类型,字符编码,文件处理

一.字符串

#需要掌握的操作
#1、strip,lstrip,rstrip
#2、lower,upper
#3、startswith,endswith
#4、format的三种玩法
#5、split,rsplit
#6、join
#7、replace
#8、isdigit

#strip
name="*Petrus**"
print(name.strip("*"))
print(name.lstrip("*"))
print(name.rstrip("*"))


#lower,upper
name="petrus"
print(name.upper())
print(name.lower())

#startswith endswith
name="Alex_SB"
print(name.strip("Alex"))
print(name.endswith("SB"))

#format的三种玩法
res="{} {} {} " .format("egon",18,"male")
res='{1} {0} {1}'.format('egon',18,'male')
res='{name} {age} {sex}'.format(sex='male',name='egon',age=18)
print(res)

#split
name='root:x:0:0::/root:/bin/bash'
print(name.split(':')) #默认分隔符为空格
name='C:/a/b/c/d.txt' #只想拿到顶级目录
print(name.split('/',1))
name="a|b|c" #从右开始切分
print(name.rsplit("|",1))

#join
tag=" "
print(tag.join(["petrus","say","hello","world"]))  #可迭代对象必须都是字符串


#replace
name="alex say :i have one tesla,my name is alex"
print(name.replace("alex","SB",1))

#isdigit:可以判断bytes和unicode类型,是最常用的用于于判断字符是否为"数字"的方法
age=input(">>>>>:")
print(age.isdigit())

其他操作

#1、find,rfind,index,rindex,count
#2、center,ljust,rjust,zfill
#3、expandtabs
#4、captalize,swapcase,title
#5、is数字系列
#6、is其他

#find,rfind,index,rindex,count
name='egon say hello'
print(name.find('o',1,3)) #顾头不顾尾,找不到则返回-1,不会报错,找到了则显示索引
print(name.index('e',2,4)) #同上,但是找不到会报错
print(name.count('e',1,3)) #顾头不顾尾,如果不指定范围则查找所有

#expandtabs:把字符串中的 tab 符号('\t')转为空格,tab 符号('\t')默认的空格数是 8。
name="egon\thello"
print(name)
print(name.expandtabs(1))

#captalize,swapcase,title
name="OldBoy"
print(name.capitalize()) #首字母大写
print(name.swapcase()) #大小写翻转
msg='egon say hi'
print(msg.title()) #每个单词的首字母大写

#is 数字系列
#在Python3中
num1=b"4" #bytes
num2=u"4" #unicode
num3="四" #中文数字
num4="IV" #罗马数字
#isdigt:bytes,unicode
print(num1.isdigit())
print(num2.isdigit())
print(num3.isdigit())
print(num4.isdigit())
"""
True
True
False
False
"""

#isdecimal:检查字符串是否只包含十进制字符。这种方法只存在于unicode对象
#注意:定义一个十进制字符串,只需要在字符串前添加 'u' 前缀即可。
#bytes类型无isdecimal方法
num1=b"4" #bytes
num2=u"4" #unicode
num3="四" #中文数字
num4="IV" #罗马数字
print(num2.isdecimal()) #True
print(num3.isdecimal()) #False
print(num4.isdecimal()) #False

#isnumberic:unicode,中文数字,罗马数字
#bytes类型无isnumberic方法
num1=b"4" #bytes
num2=u"4" #unicode
num3="四" #中文数字
num4="Ⅳ" #罗马数字
print(num2.isnumeric()) #True
print(num3.isnumeric()) #True
print(num4.isnumeric()) #True

#is其他
print('===>')
name='egon123'
print(name.isalnum()) #字符串由字母或数字组成
print(name.isalpha()) #字符串只由字母组成

print(name.isidentifier())
print(name.islower())
print(name.isupper())
print(name.isspace())
print(name.istitle())

str = "0123456789"
print(str[0:3]) #截取第一位到第三位的字符
print(str[:]) #截取字符串的全部字符
print(str[6:]) #截取第七个字符到结尾
print(str[:-3]) #截取从头开始到倒数第三个字符之前
print(str[2]) #截取第三个字符
print(str[-1]) #截取倒数第一个字符
print(str[::-1]) #创造一个与原字符串顺序相反的字符串
print(str[-3:-1]) #截取倒数第三位与倒数第一位之前的字符
print(str[-3:]) #截取倒数第三位到结尾
print (str[:-5:-3]) #逆序截取,具体啥意思没搞明白?
str1="51reboot"
print(str1[:-5:2])


"""
运行结果:
012
01234 56789
56789
01234 56
2
9
98765 43210
78
789
96
5r

"""



总结:最常用的是isdigit,可以判断bytes和unicode类型,这也是最常见的数字应用场景 如果要判断中文数字或罗马数字,则需要用到isnumeric

二.字符编码介绍

1.文本编辑器存取文件的原理(nodepad++,pycharm,word)

#1、打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的内容也都是存放与内存中的,断电后数据丢失

#2、要想永久保存,需要点击保存按钮:编辑器把内存的数据刷到了硬盘上。

#3、在我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已

2.python解释器执行py文件的原理,例如python test.py

#第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器

#第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(小复习:pyhon的解释性,决定了解释器只关心文件内容,不关心文件后缀名)

#第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码( ps:在该阶段,即真正执行代码时,才会识别python的语法,执行文件内代码,当执行到name="egon"时,会开辟内存空间存放字符串"egon")

3.什么是字符编码

计算机要想工作必须通电,即用‘电’驱使计算机干活,也就是说‘电’的特性决定了计算机的特性。电的特性即高低电平(人类从逻辑上将二进制数1对应高电平,二进制数0对应低电平),关于磁盘的磁特性也是同样的道理。结论:计算机只认识数字

  很明显,我们平时在使用计算机时,用的都是人类能读懂的字符(用高级语言编程的结果也无非是在文件内写了一堆字符),如何能让计算机读懂人类的字符?

  必须经过一个过程:
  #字符--------(翻译过程)------->数字 

  #这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

4.以下两个场景下涉及到字符编码的问题

#1、一个python文件中的内容是由一堆字符组成的,存取均涉及到字符编码问题(python文件并未执行,前两个阶段均属于该范畴)

#2、python中的数据类型字符串是由一串字符组成的(python文件执行时,即第三个阶段)

5.字符编码的发展可分为三个阶段

#阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII
ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符

ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符),后来为了将拉丁文也编码进了ASCII表,将最高位也占用了

#阶段二:为了满足中文和英文,中国人定制了GBK
GBK:2Bytes代表一个中文字符,1Bytes表示一个英文字符
为了满足其他国家,各个国家纷纷定制了自己的编码
日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里

#阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。如何解决这个问题呢???

#!!!!!!!!!!!!非常重要!!!!!!!!!!!!
说白了乱码问题的本质就是不统一,如果我们能统一全世界,规定全世界只能使用一种文字符号,然后统一使用一种编码,那么乱码问题将不复存在,
ps:就像当年秦始皇统一中国一样,书同文车同轨,所有的麻烦事全部解决
很明显,上述的假设是不可能成立的。很多地方或老的系统、应用软件仍会采用各种各样的编码,这是历史遗留问题。于是我们必须找出一种解决方案或者说编码方案,需要同时满足:
#1、能够兼容万国字符
#2、与全世界所有的字符编码都有映射关系,这样就可以转换成任意国家的字符编码

这就是unicode(定长), 统一用2Bytes代表一个字符, 虽然2**16-1=65535,但unicode却可以存放100w+个字符,因为unicode存放了与其他编码的映射关系,准确地说unicode并不是一种严格意义上的字符编码表,下载pdf来查看unicode的详情:
链接:https://pan.baidu.com/s/1dEV3RYp

很明显对于通篇都是英文的文本来说,unicode的式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的)

于是产生了UTF-8(可变长,全称Unicode Transformation Format),对英文字符只用1Bytes表示,对中文字符用3Bytes,对其他生僻字用更多的Bytes去存


#总结:内存中统一采用unicode,浪费空间来换取可以转换成任意编码(不乱码),硬盘可以采用各种编码,如utf-8,保证存放于硬盘或者基于网络传输的数据量很小,提高传输效率与稳定性。

!!!重点!!!

基于目前的现状,内存中的编码固定就是unicode,我们唯一可变的就是硬盘的上对应的字符编码。
此时你可能会觉得,那如果我们以后开发软时统一都用unicode编码,那么不就都统一了吗,关于统一这一点你的思路是没错的,但我们不可会使用unicode编码来编写程序的文件,因为在通篇都是英文的情况下,耗费的空间几乎会多出一倍,这样在软件读入内存或写入磁盘时,都会徒增IO次数,从而降低程序的执行效率。因而我们以后在编写程序的文件时应该统一使用一个更为精准的字符编码utf-8(用1Bytes存英文,3Bytes存中文),再次强调,内存中的编码固定使用unicode。
1、在存入磁盘时,需要将unicode转成一种更为精准的格式,utf-8:全称Unicode Transformation Format,将数据量控制到最精简

2、在读入内存时,需要将utf-8转成unicode
所以我们需要明确:内存中用unicode是为了兼容万国软件,即便是硬盘中有各国编码编写的软件,unicode也有相对应的映射关系,但在现在的开发中,程序员普遍使用utf-8编码了,估计在将来的某一天等所有老的软件都淘汰掉了情况下,就可以变成:内存utf-8<->硬盘utf-8的形式了。

5.总结

!!!总结非常重要的两点!!!

#1、保证不乱吗的核心法则就是,字符按照什么标准而编码的,就要按照什么标准解码,此处的标准指的就是字符编码

#2、在内存中写的所有字符,一视同仁,都是unicode编码,比如我们打开编辑器,输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不太一样。只有在我们往硬盘保存或者基于网络传输时,才能确定”你“到底是一个汉字,还是一个日本字,这就是unicode转换成其他编码格式的过程了

unicode--------->encode----------->utf-8

utf-8-------------->decode------------>unicode

5.执行python程序的三个阶段

python test.py   (我再强调一遍,执行test.py的第一步,一定是先将文件内容读入到内存中)

阶段一:启动python解释器

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

阶段三:读取已经加载到内存的代码(unicode编码格式),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon"

内存的编码使用unicode,不代表内存中全都是unicode,

在程序执行之前,内存中确实都是unicode,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode的格式存放于内存中的

但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间)用来存放python的数据类型的值,而python的字符串类型又涉及到了字符的概念

比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放字符串类型的值,至于该字符串类型的值被识别成何种编码存放,这就与python解释器的有关了,而python2与python3的字符串类型又有所不同。

三.文件内光标移动

1.read(3)

   *文件打开方式为t模式时,代表读取3个字符

   *文件打开方式为b模式时,代表读取3个字节

2.f.seek(指针移动的字节数,模式控制): 控制文件指针的移动

#模式控制:

0:默认的模式,该模式代表指针移动的字节数是以文件开头为参照的

1:该模式代表指针移动的字节数是以当前所在的位置为参照的

2:该模式代表指针移动的字节数是以文件末尾的位置为参照的

注意:1.seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,0模式既可在t模式也可以在b模式下使用,但无论哪种模式,都是以bytes为单位移动的

           2.truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试

3.f.tell()查看文件指针当前距离文件开头的位置

四.修改文件的方式

    1).修改文件的方式一:

           1.将文件内容由硬盘全部读入内存

           2.在内存中完成修改

           3.将内存中修改后的结果覆盖写回硬盘  

c.txt:
      life is short ,i need python
      python is the best language in the world
----------------------------------------------------------

with open("c.txt","rt",encoding="utf-8") as f_read:
    data=f_read.read()
    print(data,type(data))
    data1=data.replace("PYTHON","python")
    print(data1)
with open("c.txt","wt",encoding="utf-8") as f_write:
    f_write.write(data1)

           缺点:占用内存过多,不适用于大文件

      2).修改文件的方式二:

           1.以读的方式打开源文件,以写的方式打开一个临时文件

           2.从源文件中每读取一行内容修改完毕后写入临时文件,直到源文件读取完毕

           3.删掉源文件,将临时文件重命名为源文件

import  os
with open("c.txt","rt",encoding="utf-8") as read_f, open(".c.txt.temp" ,"wt",encoding="utf-8") as write_f:
    for line in read_f:
        data=line.replace("python","PYTHON")
        write_f.write(data)
os.remove("c.txt")
os.rename(".c.txt.temp","c.txt")

       优点:同一时刻在内存中只存在源文件的一行内容,不会过多的占用内存

       缺点:在文件修改的过程中会出现源文件与临时文件共存,在硬盘上同一时刻会有两份数据,会过多的占用硬盘

    

    ===================================================================

    练习:

1、python test.py执行的三个阶段是什么?在哪个阶段识别文件内的python语法?

第一阶段:启动python解释器
第二阶段:python解释器将test.py文件从硬盘中加载到内存
第三阶段:读取已经加载到内存的代码,然后执行,此阶段python解释器会识别文件内的python语法,可能会开辟新的内存空间

2.将下述两个变量的值交换

s1="alex"
s2="SB"
s1,s2=s2,s1
print(s1,s2)

3.判断下述结果 (is比较的是id,而双等号比较的是值)

msg1='alex say my name is alex,my age is 73,my sex is female'
msg2='alex say my name is alex,my age is 73,my sex is female'
msg1 is msg2  #False
msg1 == msg2  #True

4.什么是常量?在python中如何定义常量

所谓常量,本质上也是变量,只是常量的值是只读的,不能改变,在python中可以将变量名大写来定义常量

5.有存放用户信息的列表如下,分别存放用户的名字、年龄、公司信息

userinfo={
			'name':'egon',
			'age':18,
			'company_info':{
				'cname':'oldboy',
				'addr':{
					'country':'China',
					'city':'Shanghai',
				}
			}

		}
# 要求取出该用户公司所在的城市
print(userinfo["company_info"]["addr"]["city"])

students=[
		    {'name':'alex','age':38,'hobbies':['play','sleep']},
		    {'name':'egon','age':18,'hobbies':['read','sleep']},
		    {'name':'wupeiqi','age':58,'hobbies':['music','read','sleep']},
		]
#取第二个学生的第二个爱好
print(students[1]["hobbies"][1])

#要求取出三名学生的详细信息分别赋值给三个变量(用一行代码实现) 解压赋值
a,b,c=students

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值