Python中关于coding=utf-8以及中文字符前加u的解释

写了很久的Python了,每次写之前都要在开头加上coding=utf-8,只知道是设置编码格式,但并没有太在意,今天在写socket编程时才发现编码格式的重要性。

一、关于开头coding=utf-8

开头的coding=utf-8和coding:utf-8的作用是一样的。

它们的作用都是声明python代码的文本格式是utf-8编码的,也即告诉python解释器要按照utf-8编码的方式来读取程序。

如果不加这个声明,无论代码中还是注释中有中文都会报错。

以下几种方式都可以:

# coding=utf-8

a = 10
print '这是内容'
# coding:utf-8

a = 10
print '这是内容'

注意一点无论中间是:还是=,其中coding与它们之间都不能有空格。否则也会报错。

注意:以上是针对Python2.x的版本而言,因为在Python2.x的版本中文本默认采用的是ASCII编码方式,而Python3.x的版本中,默认使用的就是UTF-8编码格式,所以就不需要在前面进行声明了。

二、关于中文字符前面的u

首先,我们先从最开始的ASCII编码开始说起,我们知道计算机在处理程序时是看不懂文字的,它眼里只有0/1数字。所以最开始的ASCII编码是通过1个字节也就是8bit来表示英文字符。因为8个二进制位可以表示出256中状态,所以用来表示英文字符绰绰有余,因此ASCII码只用到了8个二进制中的后七位,也就是可以得到128个字符。

但是像一些其他语言的字符想通过最多只能表示256个字符的ASCII编码来表示就不太实际了。我们中华文明博大精深,光汉字就有超过6万多,所以必须有一种可以表示更多字符的编码方式,如常见的GB2312编码方式,它是通过两个字节来表示一个汉字,这样最多就可以表示256*256=65536个字符了。

而由于GB2312不能处理一些古汉语或者人名中的一些罕见字,所以导致了后面的GBK编码GB18030编码方式的出现。其中,GBK也是双字节的编码方式,并且GBK字符集中共收入了21886个汉字和图像符号。除此之外,GBK还可以与GB 2312完全兼容。

既然对于每种语言都有其对应的字符集,那么是否存在一种字符集可以包含世界上所有的符号呢。所以产生了Unicode编码。Unicode编码为世界上所有的语言的每个字符都设定了唯一的二进制编码,这样就可以实现跨语言进行文本转换和传输了。

通过Unicode进行编码时,不同字符所占用的位的长度是不同的,也就是说有的字符编码仅需要几位,而有的则需要十几位,这就导致了如果都采用固定长度的编码时,就会造成空间的浪费。所以就衍生出了对于Unicode编码的不同实现方式,如常见到的UTF-8UTF-16UTF-32,其中UTF-8是最为常用的编码方式,它采用了变长字节的表示方式,即使用的字节数是可变的,这个变化是根据字符对应的Unicode编号的大小所变化的,即编号小的字符使用的字节数就少,编号大的字符使用的字节数就多,因此,使用的字节个数从1到4个不等。

所以,回到主题,Python中用到的字符串前面加上u的作用是声明对后面的字符串进行unicode编码,常用于中文字符串的处理。Unicode是书写国际文本的标准方法,如果你想用你的母语来写文本的时候,就需要一个支持Unicode的编译器,Python允许处理Unicode文本,只需在字符串前加上前缀u即可。一般英文的字符串不需要进行任何编码的处理,但是当你使用中文的时候,就需要在前面加上u了。

 

最后再引用知乎上某个大佬举的例子来加深理解一下:https://www.zhihu.com/question/23374078/answer/65352538

 

举一个例子:It's 知乎日报

你看到的unicode字符集是这样的编码表:

I 0049
t 0074
' 0027
s 0073
  0020
知 77e5
乎 4e4e
日 65e5
报 62a5

每一个字符对应一个十六进制数字。

计算机只懂二进制,因此,严格按照unicode的方式(UCS-2),应该这样存储:

I 00000000 01001001
t 00000000 01110100
' 00000000 00100111
s 00000000 01110011
  00000000 00100000
知 01110111 11100101
乎 01001110 01001110
日 01100101 11100101
报 01100010 10100101

这个字符串总共占用了18个字节,但是对比中英文的二进制码,可以发现,英文前9位都是0!浪费啊,浪费硬盘,浪费流量。

怎么办?

UTF。

UTF-8是这样做的:

1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;

2. n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。

这样就形成了如下的UTF-8标记位:

0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
... ...

于是,”It's 知乎日报“就变成了:

I 01001001
t 01110100
' 00100111
s 01110011
  00100000
知 11100111 10011111 10100101
乎 11100100 10111001 10001110
日 11100110 10010111 10100101
报 11100110 10001010 10100101

和上边的方案对比一下,英文短了,每个中文字符却多用了一个字节。但是整个字符串只用了17个字节,比上边的18个短了一点点。

另外一个汉字在UTF-8编码的情况下可能需要三个字节,而使用gbk两个字节就足够了,所以有时候为了节省流量和硬盘,在使用中文的时候,也有用gbk或者gbk2312编码的。

 

 

 

 

 

 

  • 33
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Spring Boot中,可以使用@Value注解来获取环境变量。在旧版本中,可以使用@Value("${spring.profiles.active}")来获取spring.profiles.active的值。然而,在升级到新版本后,这种方式可能会提示异常。在新版本中,可以使用新的配置方式来获取环境变量。具体来说,可以使用@Value("${spring.config.activate.on-profile}")来获取spring.profiles.active的值。\[1\] 另外,还可以通过在java程序启动时指定参数来获取classpath下的文件。这可以通过在启动命令中使用-D参数来指定系统属性,然后在代码中使用@Value注解来获取该属性的值。\[2\] 此外,还可以使用@Configuration注解和@Profile注解来实现特异化配置。通过在配置类上使用@Profile注解,并指定特定的profile名称,可以使得该配置类只在对应的profile激活时生效。\[3\] #### 引用[.reference_title] - *1* *2* [spring boot2.5x、2.6x获取环境变量(spring.profiles.active),获取classpath下文件方法](https://blog.csdn.net/qq_41070393/article/details/123950153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [【springbootSpringBoot 配置文件中 spring.profiles.active 配置详解](https://blog.csdn.net/qyj19920704/article/details/127699920)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值