一句话,一篇文章,在编程语言里怎么表达?我们用字符串来表达:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def main():
s1 = 'Hello world!'
s2 = "Hello world!"
s3 = '''Hello world!'''
s4 = """Hello world!"""
print(s1)
print(s2)
print(s3)
print(s4)
if __name__ == '__main__':
main()
结果将在屏幕上打印一行:Hello world!
这四种表达方式有什么区别?
‘’和“”一样,可以表达单行字符串。看看如下表达:
s5 = 'The is a "'
s6 = "The is a '"
print(s5)
print(s6)
再看如下表达:
s7 = 'The is a \''
s8 = "The is a \""
print(s7)
print(s8)
最后看多行的表达情况:
def test4():
s1 = '''
The first wealth is health,
Believe in yourself!
'''
print(s1)
s2 = """
健康是人生第一财富,
相信你自己!
"""
print(s2)
如果字符串里的字符一直是英语就简单了,可是国家这么多,语言也就注定不会少,字符串是怎么存储的?这要从计算机最基础的存储知识讲起,又不能太细节,总之字符知识没我们看字符串表面那么简单。
最小存储单元叫位,Bit, 也直译为比特,取值[0, 1], 好像开关一样,也叫二进制,还记得《三体》里秦始皇搞计算的场景吧。
其次的存储单元叫字节Byte, 1Byte = 8Bit, 一个字节由8位来组成。1个字节的取值范围是【0, 2^8 - 1】,也就是[0, 255],共256种取值。
我们说字符串由多个字符组成,字符包括字母、数字、符号和汉字等。1个字符在存储上占用多少个字节呢?这个问题有点复杂。
反正计算机底层只会存储0和1这样的Bit,1个字节8位,取值就是256种。
用1个字节来表达1个字符怎么样?计算机首先是欧美人发明的,他们就是怎么干的,到底字母A用多少数字表达,需要一个统一的标准,美国人就搞了一个标准:ASCII (American Standard Code for Information Interchange):美国信息交换标准代码,所以英文中的字母、数字和符号的表达和存储问题就解决了。
后来计算机推广到其它国家,碰到了不同语言文字,比如中文、日文、韩文等等,ASCII就不够用了,于是各种编码标准就诞生了:GB2312、Unicode、UTF-8、UTF-16、UTF-32等。
记得二十年前我们编程时还喜欢用GB2312, 现在基本只用Unicode和UTF-8,当然这种讲法也不严谨,不过在Python3里,大家通常简单讲法就是:
1)在内存中采用Unicode编码来存储字符串。
2)在代码文件里采用UTF-8编码来存储字符串。
实际上Unicode只是一个字符集,它只规定了各个字符所对应的二进制数,并没有规定在计算机中如何存储以及传输的问题。
在Unicode字符集下,具体的字符编码又细分为:
1)UCS: Unicode的定长字符编码,包括UCS2和UCS4。
2)UTF:Unicode的变长字符编码, 包括UTF-8, UTF-16和UTF-32。
Unicode当前默认的版本是UCS-2,UCS-2 编码 与 Unicode码 完全一样。
UTF-8 |
UTF-16 | UTF-32 | UCS-2 | UCS-4 | |
编码空间 | 0 ~ 10FFFF | 0 ~ 10FFFF | 0 ~ 10FFFF | 0 ~ FFFF | 0 ~ 7FFFFFFF |
最少编码字节数 | 1 | 2 | 4 | 2 | 4 |
最多编码字节数 | 4 | 4 | 4 | 2 | 4 |
是否依赖字节序 | 否 | 是 | 是 | 是 | 是 |
两个问题:
1)为什么代码文件里内容要采用UTF-8编码?
2)为什么内存中的字符串要采用UCS2编码?
来一点测试代码,让我们感性认识一下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def test():
s1 = 'abc123'
b1 = s1.encode('UTF-8')
print(s1)
print(len(s1), type(s1))
print(b1)
print(len(b1), type(b1))
s2 = '我是中国人ab12'
b2 = s2.encode('UTF-8')
print(s2)
print(len(s2), type(s2))
print(b2)
print(len(b2), type(b2))
def main():
test()
if __name__ == '__main__':
main()
运行结果如下:
abc123
6
b'abc123'
6
我是中国人ab12
9
b'\xe6\x88\x91\xe6\x98\xaf\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xbaab12'
19
如上图所示,在UTF-8编码里,英文字母和数字占一个字节,而一个中文汉字占3个字节。注意,对Unicode编码的字符串求长度,输出的是多少个字符,而不是内存中的字节数。
字符串的知识点很多,我们在后面的章节还要讲解,这里暂且到此为止。