一文带你了解Python中的字符串是什么


Posted in Python onNovember 20, 2018

在《 详解Python拼接字符串的七种方式 》这篇文章里,我提到过,字符串是程序员离不开的事情。后来,我看到了一个英文版本的说法:

There are few guarantees in life: death, taxes, and programmers needing to deal with strings.
它竟然把程序员处理字符串跟死亡大事并列了,可见这是多么命中注定……

回头看其它文章,我发现这种说法得到了佐证,因为我在无意中已零零碎碎地提及了字符串的很多方面,例如:字符串读写文件、字符串打印、字符串不可变性、字符串Intern机制、字符串拼接、 是否会取消字符串 ,等等。而这些,还只能算字符串面目的冰山一角。

既然如此,那干脆再单独写写Python的字符串吧。这篇内容可能会很基(li)础(lun),并不是什么“骚操作”或“冷知识”,权当是一份温故而求知新的笔记。

1 Python字符串是什么?

根据维基百科定义:字符串是由零个或多个字符组成的有限序列。而在Python 3中,它有着更明确的意思: 字符串是由Unicode码点组成的不可变序列 (Strings are immutable sequences of Unicode code points.)

字符串是一种序列,这意味着它具备序列类型都支持的操作:

# 以下的s、t皆表示序列,x表示元素
x in s # 若s包含x,返回True,否则返回False
x not in s # 若s包含x,返回False,否则返回True
s + t # 连接两个序列
s * n # s复制n次
s[i] # s的索引第i项
s[i:j] # s切片从第i项到第j-1项
s[i:j:k] # s切片从第i项到第j-1项,间隔为k
len(s) # s的长度
min(s) # s的最小元素
max(s) # s的最大元素
s.index(x) # x的索引位置
s.count(x) # s中出现x的总次数

字符串序列还具备一些特有的操作,限于篇幅,按下不表。预告一下,下一篇《 你真的知道Python的字符串怎么用吗? 》将会展开介绍,敬请期待……

字符串序列是一种不可变序列,这意味着它不能像可变序列一样,进行就地修改。例如,在字符串“Python”的基础上拼接“Cat”,得到字符串“PythonCat”,新的字符串是一个独立的存在,它与基础字符串“Python”并没有关联关系。

basename = "Python"
myname = basename + "Cat"
id(basename) == id(myname) >>> False
# 作为对比,列表能就地修改
baselist = ["Python"]
baselist.append("Cat")
print(baselist) >>> ['Python', 'Cat']

字符串这种序列与其它序列(如列表、元组)的不同之处在于,它的“元素”限定了只能是Unicode码点。Unicode码点是什么呢?简单理解,就是用Unicode编码的字符。那字符是什么呢? 字符 是人类书写系统的各类符号,例如阿拉伯数字、拉丁字母、中文、日文、藏文、标点符号、控制符号(换行符、制表符等)、其它特殊符号(@#¥%$*等等)。那Unicode编码又是什么呢?Unicode别名是万国码、国际码,它是一种适用性最广的、将书写字符编码为计算机数字的标准。

总所周知,在最底层的计算机硬件世界里,只有0和1。那么,怎么用这个二进制数字,来表示人类的文化性的字符呢?这些字符数量庞大,而且还在日益增长与变化,什么样的编码方案才是最靠谱的呢?

历史上,人类创造了多种多样的字符编码标准,例如ASCII(1963年)编码,以西欧语言的字符为主,它的缺点是只能编码128个字符;例如GB2312(1981年),这是中国推出的编码标准,在兼容ASCII标准的基础上,还加入了对日文、俄文等字符的编码,但缺点仍是编码范围有限,无法表示古汉语、繁体字及更多书写系统的字符。

Unicode编码标准于1991年推出,至今迭代到了第11版,已经能够编码146个书写系统的130000个字符,可谓是无所不包,真不愧是“国际码”。Unicode编码其实是一个二进制字符集,它建立了从书写字符映射成唯一的数字字符的关系,但是,由于各系统平台对字符的理解差异,以及出于节省空间的考虑,Unicode编码还需要再做一次转换,转换后的新的二进制数字才能作为 实际存储及网络传输时的编码 。

这种转换方式被称为 Unicode转换格式 (Unicode Transformation Format,简称为UTF),它又细分为UTF-8、UTF-16、UTF-32等等方式。我们最常用的是UTF-8。为什么UTF-8最常用呢?因为它是可变长度的编码方案,针对不同的字符使用不同的字节数来编码,例如编码英文字母时,只需要一个字节(8个比特),而编码较复杂的汉字时,就会用到三个字节(24个比特)。

一文带你了解Python中的字符串是什么

二进制的编码串可以说是给机器阅读的,为了方便,我们通常会将其转化为十六进制,例如“中”字的Unicode编码可以表示成 0x4e2d ,其UTF-8编码可以表示为 0xe4b8ad ,'0x'用于开头表示十六进制,这样就简洁多了。不过,UTF-8编码的结果会被表示成以字节为单位的形式,例如“中”字用UTF-8编码后的字节形式是 \xe4\xb8\xad 。

Python中为了区分Unicode编码与字节码,分别在开头加“u”和“b”以示区分。在Python 3中,因为Unicode成了默认编码格式,所以“u”被省略掉了。

# 字符转Unicode编码
# Python3中,开头的u被省略,b不可省略
hex(ord('中')) >>> '0x4e2d'
hex(ord('A')) >>> '0x41'
# 字符转UTF-8编码(encode)
'中'.encode('utf-8') >>> b'\xe4\xb8\xad'
'A'.encode('utf-8') >>> b'A'
# Unicode编码还原成字符
chr(0x4e2d) >>> '中'
chr(0x41) >>> 'A'
# UTF-8编码还原成字符(decode)
b'\xe4\xb8\xad'.decode('utf-8') >>> '中'
b'A'.decode('utf-8') >>> 'A'

总结一下,Python 3 中的字符串是由Unicode码点组成的不可变序列,也即是,由采用Unicode标准编码的字符组成的不可变序列。Unicode编码将书写系统的字符映射成了计算机二进制数字,为了方便,通常显示为十六进制;在运算内存中,字符以Unicode编码呈现,当写入磁盘或用于网络传输时,一般采用UTF-8方式编码。

在Python 2中,因为历史包袱,即Python先于Unicode编码而诞生,所以其编码问题是个大难题。幸好抛弃Python 2已成大势所趋,所以我就不再对此做介绍或比对了。

2 Python字符串 VS Java字符串

虽然不提纵向版本间的差异,但是,我想将Python字符串与其它编程语言做一个横向对比。我觉得这会是挺好玩的事。通过跨语言的比较,也许我们能加深对一个事物(字符串)的理解,还可能受到启发,得到对“编程语言”及“编程哲学”的领悟。

由于本人才疏学浅,本文就只对两点皮毛特性作说明,欢迎读者斧正和补充。

(1)字符串的定义方式

Python的字符串是内置类型,所以使用起来很方便,有如下三种定义方式:

str_0 = '''Python字符串可以写在用三引号对内,表示多行字符串。
还可以写在单引号对内,
当然还可以写在双引号对内。
'''
str_1 = 'Python猫是一只猫'
str_2 = "Python猫是一个微信公众号"

Java的字符串不是内置类型,它属于对象,需要通过String类来创建。不过,正因为字符串太常用,所以Java特意预定义了一个字符串类String,使得程序员也可以像这样来定义: String name = "Python猫"; ,而不必这样写: String name = new String("Python猫"); 。

Java的字符串只能写在双引号内,不具备Python中单双引号混用的灵活。至于三引号的多行字符串表示法,Java程序员表示羡慕得要死,那种痛苦,受过折磨的人最懂。写出来让Python程序员开心一下:

String s = "Java 的多行字符串很麻烦,\n"
  + "既要使用换行符,\n"
  + "还需要使用加号拼接";

为什么Java不支持多行字符串、什么时候支持多行字符串?此类问题在Python程序员眼里,可能很费解,但它绝对能排进“Java程序员最希望能实现的特性”的前列。好不容易,官方有计划在Java 11 实现,但今年9月发布的Java 11 仍是没有,现在改计划到Java 12 了。

(2)单个字符与字符序列

Java中其实也有单引号的使用,用在char类型上,例如 char c = 'A'; 。char是一种内置类型,表示单个用Unicode编码的字符。Python中没有char类型,字符串类型通吃一切。

前面说到,Python的字符串是一种字符序列,而Java的字符串并不是一种序列,要表示相近的概念的话,就得用到 字符数组 或者 字符串数组 ,例如:

char[] a = { 'a', 'b', 'c'}; 
String[] str = new String[]{"1","2","3"};

字符数组和字符串数组是一种序列,但并不是字符串,它们之间如果要相互转换,还是挺麻烦的。另外,说是序列,但Java的序列操作绝对无法跟Python相比,别的不说,就上面提及的几个基础操作,试问Java能否实现、实现起来要花费多大力气?

最后来个Ending,关于“Python字符串到底是什么”就说到这啦,希望对你有所帮助。下次,我再跟大家说说“Python字符串到底怎么用”,敬请期待。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python修改注册表终止360进程实例
Oct 13 Python
Django中更新多个对象数据与删除对象的方法
Jul 17 Python
Python脚本暴力破解栅栏密码
Oct 19 Python
python去除文件中空格、Tab及回车的方法
Apr 12 Python
python使用标准库根据进程名如何获取进程的pid详解
Oct 31 Python
从请求到响应过程中django都做了哪些处理
Aug 01 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
Dec 18 Python
Python 20行简单实现有道在线翻译的详解
May 15 Python
解决Django layui {{}}冲突的问题
Aug 29 Python
python logging添加filter教程
Dec 24 Python
Python开发.exe小工具的详细步骤
Jan 27 Python
高考要来啦!用Python爬取历年高考数据并分析
Jun 03 Python
pygame游戏之旅 创建游戏窗口界面
Nov 20 #Python
pygame游戏之旅 python和pygame安装教程
Nov 20 #Python
python2和python3的输入和输出区别介绍
Nov 20 #Python
python使用pygame框架实现推箱子游戏
Nov 20 #Python
浅析python的优势和不足之处
Nov 20 #Python
opencv实现图片模糊和锐化操作
Nov 19 #Python
python实现朴素贝叶斯算法
Nov 19 #Python
You might like
Thinkphp5行为使用方法汇总
2017/12/21 PHP
PHP简单验证码功能机制实例详解
2019/03/27 PHP
Laravel实现批量更新多条数据
2020/04/06 PHP
可输入的下拉框
2006/06/19 Javascript
JQuery里选择超链接的实现代码
2011/05/22 Javascript
js模拟滚动条(横向竖向)
2013/02/22 Javascript
javascript中的document.open()方法使用介绍
2013/10/09 Javascript
JQuery替换DOM节点的方法
2015/06/11 Javascript
实例讲解JS中setTimeout()的用法
2016/01/28 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
2016/04/19 Javascript
vue.js指令v-model实现方法
2016/12/05 Javascript
Angular下H5上传图片的方法(可多张上传)
2017/01/09 Javascript
使用vue实现点击按钮滑出面板的实现代码
2017/01/10 Javascript
Javascript实现动态时钟效果
2018/11/17 Javascript
详解javascript设计模式三:代理模式
2019/03/25 Javascript
Vue Components 数字键盘的实现
2019/09/18 Javascript
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
python中requests使用代理proxies方法介绍
2017/10/25 Python
Python pymongo模块用法示例
2018/03/31 Python
Python 修改列表中的元素方法
2018/06/26 Python
pygame实现俄罗斯方块游戏(基础篇2)
2019/10/29 Python
详解python中的lambda与sorted函数
2020/09/04 Python
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
台湾良兴购物网:EcLife
2019/12/01 全球购物
戴尔荷兰官方网站:Dell荷兰
2020/10/04 全球购物
日化店促销方案
2014/03/26 职场文书
体育系毕业生求职自荐信
2014/04/16 职场文书
管理标语大全
2014/06/24 职场文书
公司年底活动方案
2014/08/17 职场文书
幼儿园迎国庆65周年活动策划方案
2014/09/16 职场文书
裁员通知
2015/04/25 职场文书
如何使用JavaScript策略模式校验表单
2021/04/29 Javascript
Python数据分析入门之数据读取与存储
2021/05/13 Python
Nginx配置Https安全认证的实现
2021/05/26 Servers
JavaScript 定时器详情
2021/11/11 Javascript
Spring事务管理下synchronized锁失效问题的解决方法
2022/03/31 Java/Android