目次
このセクションの内容:
1. はじめに
三、Python中的默认编码
1. Python源代码文件的执行过程
2. 默认编码
3. 最佳实践
四、Python2与Python3中对字符串的支持
Python3
五、字符编码转换
Python2中的字符串进行字符编码转换过程是:
Python3中定义的字符串默认就是unicode,因此不需要先解码,可以直接编码成新的字符编码:
ホームページ バックエンド開発 Python チュートリアル Python の文字列と文字エンコーディングの問題を解決する方法

Python の文字列と文字エンコーディングの問題を解決する方法

Mar 25, 2017 pm 02:46 PM

このセクションの内容:


  1. はじめに

  2. 関連概念

  3. Python のデフォルトのエンコーディング

  4. Python2 および Python3 での文字列サポート

  5. 文字エンコーディングの変換

1. はじめに


Python の文字エンコーディングは一般的なトピックであり、同僚がこの点に関して多くの記事を書いています。言われたことをそのまま実行する人もいれば、徹底的に書く人もいます。最近、この問題について再び話されている有名な研修機関の指導ビデオを拝見しましたが、まだ説明が不十分だったので、この記事を書きたいと思いました。関連する知識を整理したい一方で、他の人に役立つことを願っています。

Python2 のデフォルトエンコーディングは、中国語の文字を認識できない ASCII であり、文字エンコーディングは明示的に指定する必要があります。Python3 のデフォルトエンコーディングは、中国語の文字を認識できます。

「Pythonによる中国語処理」について、上記のような説明を多くの記事でご覧になったことがあると思いますが、このような説明を初めて見たときは本当に理解できたと思います。しかし、長い時間が経って、関連する問題に何度も遭遇すると、よく理解できていないように感じるでしょう。上記のデフォルトのエンコーディングが何であるかを理解すると、その文の意味がより明確に理解できるようになります。

「文字エンコーディングとは」および「文字エンコーディングの開発プロセス」はこのセクションで説明するトピックではないことに注意してください。これらの内容については、以前の <> .

2. 関連概念


1. 文字とバイト

文字は人間が認識できる記号であり、これらの記号を計算ストレージに保存するには、コンピューターが認識するバイトが必要です。多くの場合、文字には複数の表現方法があり、表現方法が異なれば使用するバイト数も異なります。ここで説明するさまざまな表現方法は、文字エンコーディングを指します。たとえば、文字 A ~ Z は、ASCII コード (1 バイトを占有する)、UNICODE (2 バイトを占有する)、または UTF-8 (1 バイトを占有する) で表現できます。文字エンコーディングの役割は、人間が認識できる文字を機械が認識できるバイトコードに変換し、その逆の処理を行うことです。

UNICDOEは実際の文字列であり、ASCII、UTF-8、GBKなどの文字エンコーディングはバイト文字列を表します。これに関しては、Pythonの公式ドキュメントでも「Unicode文字列」「Unicode文字列をバイト列に変換する」といった記述がよく見られます

私たちはコードをファイルに書き、文字は次の形式でファイルに格納されます。バイト列なので、ファイル内に文字列を定義するときにバイト文字列として扱われることは理解できます。ただし、必要なのはバイト文字列ではなく文字列です。優れたプログラミング言語は、この 2 つの関係を厳密に区別し、賢明で完璧なサポートを提供する必要があります。 JAVA 言語は非常に優れているため、Python や PHP について学ぶまでは、プログラマーが扱うべきではないこれらの問題について考えたこともありませんでした。残念ながら、多くのプログラミング言語は「文字列」と「バイト文字列」を混同しようとしています。PHP と Python2 はどちらもこの種のプログラミング言語に属します。この問題を最もよく示す操作は、中国語の文字を含む文字列の長さを取得することです:

  • 文字列の長さを取得すると、結果は中国語でも英語でも、すべての文字列の数になるはずです

  • 文字列の場合対応するバイト文字列の長さは、エンコード プロセスで使用される文字エンコードに関連します (例: UTF-8 エンコード、中国語の文字を表すには 3 バイトが必要、GBK エンコード、中国語の文字は 2 バイトで表されます)

注: Windows の cmd ターミナルのデフォルトの文字エンコーディングは GBK であるため、cmd で入力された中国語の文字は 2 バイトで表現される必要があります

>>> # Python2
>>> a = &#39;Hello,中国&#39;  # 字节串,长度为字节个数 = len(&#39;Hello,&#39;)+len(&#39;中国&#39;) = 6+2*2 = 10
>>> b = u&#39;Hello,中国&#39;  # 字符串,长度为字符个数 = len(&#39;Hello,&#39;)+len(&#39;中国&#39;) = 6+2 = 8
>>> c = unicode(a, &#39;gbk&#39;)  # 其实b的定义方式是c定义方式的简写,都是将一个GBK编码的字节串解码(decode)为一个Uniocde字符串
>>> 
>>> print(type(a), len(a))
(<type &#39;str&#39;>, 10)
>>> print(type(b), len(b))
(<type &#39;unicode&#39;>, 8)
>>> print(type(c), len(c))
(<type &#39;unicode&#39;>, 8)
>>>
ログイン後にコピー

Python3 での文字列のサポートが大幅に改善されました 変更点、具体的な内容が導入されます下に。

2. エンコードとデコード

まず、一般的な科学を実行します。UNICODE 文字エンコードも文字と数値のマッピングですが、ここでの数値はコード ポイントと呼ばれ、実際には 16 進数です。

公式の Python ドキュメントには、Unicode 文字列、バイト文字列、エンコーディングの関係について次の説明があります:

Unicode 文字列はコード ポイントのシーケンスであり、コード ポイント値の範囲は 0 から 0x10FFFF です (対応する 10 進数値は 1114111 です) )。このコード ポイントのシーケンスは、ストレージ (メモリや物理ディスクを含む) 内でバイトのセット (0 ~ 255 の値) として表現される必要があり、Unicode 文字列をバイト シーケンスに変換するための規則はエンコーディングと呼ばれます。

ここで言及するエンコーディングは文字エンコーディングを指すのではなく、エンコーディングプロセスと、このプロセスで使用される

Unicode文字コードポイントとバイトのマッピングルールを指します。このマッピングは単純な 1 対 1 マッピングである必要はないため、エンコード プロセスで考えられるすべての Unicode 文字を処理する必要はありません。例:

将Unicode字符串转换为ASCII编码的规则很简单--对于每个代码点:

  • 如果代码点数值<128,则每个字节与代码点的值相同

  • 如果代码点数值>=128,则Unicode字符串无法在此编码中进行表示(这种情况下,Python会引发一个UnicodeEncodeError异常)

将Unicode字符串转换为UTF-8编码使用以下规则:

  • 如果代码点数值<128,则由相应的字节值表示(与Unicode转ASCII字节一样)

  • 如果代码点数值>=128,则将其转换为一个2个字节,3个字节或4个字节的序列,该序列中的每个字节都在128到255之间。

简单总结:

  • 编码(encode):将Unicode字符串(中的代码点)转换特定字符编码对应的字节串的过程和规则

  • 解码(decode):将特定字符编码的字节串转换为对应的Unicode字符串(中的代码点)的过程和规则

可见,无论是编码还是解码,都需要一个重要因素,就是特定的字符编码。因为一个字符用不同的字符编码进行编码后的字节值以及字节个数大部分情况下是不同的,反之亦然。

三、Python中的默认编码


1. Python源代码文件的执行过程

我们都知道,磁盘上的文件都是以二进制格式存放的,其中文本文件都是以某种特定编码的字节形式存放的。对于程序源代码文件的字符编码是由编辑器指定的,比如我们使用Pycharm来编写Python程序时会指定工程编码和文件编码为UTF-8,那么Python代码被保存到磁盘时就会被转换为UTF-8编码对应的字节(encode过程)后写入磁盘。当执行Python代码文件中的代码时,Python解释器在读取Python代码文件中的字节串之后,需要将其转换为UNICODE字符串(decode过程)之后才执行后续操作。

上面已经解释过,这个转换过程(decode,解码)需要我们指定文件中保存的字节使用的字符编码是什么,才能知道这些字节在UNICODE这张万国码和统一码中找到其对应的代码点是什么。这里指定字符编码的方式大家都很熟悉,如下所示:

# -*- coding:utf-8 -*-
ログイン後にコピー

2. 默认编码

那么,如果我们没有在代码文件开始的部分指定字符编码,Python解释器就会使用哪种字符编码把从代码文件中读取到的字节转换为UNICODE代码点呢?就像我们配置某些软件时,有很多默认选项一样,需要在Python解释器内部设置默认的字符编码来解决这个问题,这就是文章开头所说的“默认编码”。因此大家所说的Python中文字符问题就可以总结为一句话:当无法通过默认的字符编码对字节进行转换时,就会出现解码错误(UnicodeEncodeError)

Python2和Python3的解释器使用的默认编码是不一样的,我们可以通过sys.getdefaultencoding()来获取默认编码:

>>> # Python2
>>> import sys
>>> sys.getdefaultencoding()
&#39;ascii&#39;

>>> # Python3
>>> import sys
>>> sys.getdefaultencoding()
&#39;utf-8&#39;
ログイン後にコピー

因此,对于Python2来讲,Python解释器在读取到中文字符的字节码尝试解码操作时,会先查看当前代码文件头部是否有指明当前代码文件中保存的字节码对应的字符编码是什么。如果没有指定则使用默认字符编码"ASCII"进行解码导致解码失败,导致如下错误:

SyntaxError: Non-ASCII character &#39;\xc4&#39; in file xxx.py on line 11, but no encoding declared; 
see http://python.org/dev/peps/pep-0263/ for details
ログイン後にコピー

对于Python3来讲,执行过程是一样的,只是Python3的解释器以"UTF-8"作为默认编码,但是这并不表示可以完全兼容中文问题。比如我们在Windows上进行开发时,Python工程及代码文件都使用的是默认的GBK编码,也就是说Python代码文件是被转换成GBK格式的字节码保存到磁盘中的。Python3的解释器执行该代码文件时,试图用UTF-8进行解码操作时,同样会解码失败,导致如下错误:

SyntaxError: Non-UTF-8 code starting with &#39;\xc4&#39; in file xxx.py on line 11, but no encoding declared; 
see http://python.org/dev/peps/pep-0263/ for details
ログイン後にコピー

3. 最佳实践

  • 创建一个工程之后先确认该工程的字符编码是否已经设置为UTF-8

  • 为了兼容Python2和Python3,在代码头部声明字符编码:-*- coding:utf-8 -*-

四、Python2与Python3中对字符串的支持


其实Python3中对字符串支持的改进,不仅仅是更改了默认编码,而是重新进行了字符串的实现,而且它已经实现了对UNICODE的内置支持,从这方面来讲Python已经和JAVA一样优秀。下面我们来看下Python2与Python3中对字符串的支持有什么区别:

Python2

Python2中对字符串的支持由以下三个类提供

class basestring(object)
    class str(basestring)
    class unicode(basestring)
ログイン後にコピー

执行help(str)和help(bytes)会发现结果都是str类的定义,这也说明Python2中str就是字节串,而后来的unicode对象对应才是真正的字符串。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

a = &#39;你好&#39;
b = u&#39;你好&#39;

print(type(a), len(a))
print(type(b), len(b))

输出结果:

(<type &#39;str&#39;>, 6)
(<type &#39;unicode&#39;>, 2)
ログイン後にコピー

Python3

Python3中对字符串的支持进行了实现类层次的上简化,去掉了unicode类,添加了一个bytes类。从表面上来看,可以认为Python3中的str和unicode合二为一了。

class bytes(object)
class str(object)
ログイン後にコピー

实际上,Python3中已经意识到之前的错误,开始明确的区分字符串与字节。因此Python3中的str已经是真正的字符串,而字节是用单独的bytes类来表示。也就是说,Python3默认定义的就是字符串,实现了对UNICODE的内置支持,减轻了程序员对字符串处理的负担。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

a = &#39;你好&#39;
b = u&#39;你好&#39;
c = &#39;你好&#39;.encode(&#39;gbk&#39;)

print(type(a), len(a))
print(type(b), len(b))
print(type(c), len(c))

输出结果:

<class &#39;str&#39;> 2
<class &#39;str&#39;> 2
<class &#39;bytes&#39;> 4
ログイン後にコピー

五、字符编码转换


上面提到,UNICODE字符串可以与任意字符编码的字节进行相互转换,如图:

那么大家很容易想到一个问题,就是不同的字符编码的字节可以通过Unicode相互转换吗?答案是肯定的。

Python2中的字符串进行字符编码转换过程是:

字节串-->decode('原来的字符编码')-->Unicode字符串-->encode('新的字符编码')-->字节串

#!/usr/bin/env python
# -*- coding:utf-8 -*-

utf_8_a = &#39;我爱中国&#39;
gbk_a = utf_8_a.decode(&#39;utf-8&#39;).encode(&#39;gbk&#39;)
print(gbk_a.decode(&#39;gbk&#39;))

输出结果:

我爱中国
ログイン後にコピー
Python3中定义的字符串默认就是unicode,因此不需要先解码,可以直接编码成新的字符编码:

字符串-->encode('新的字符编码')-->字节串

#!/usr/bin/env python
# -*- coding:utf-8 -*-
utf_8_a = &#39;我爱中国&#39;
gbk_a = utf_8_a.encode(&#39;gbk&#39;)
print(gbk_a.decode(&#39;gbk&#39;))

输出结果:

我爱中国
ログイン後にコピー

最后需要说明的是,Unicode不是有道词典,也不是google翻译器,它并不能把一个中文翻译成一个英文。正确的字符编码的转换过程只是把同一个字符的字节表现形式改变了,而字符本身的符号是不应该发生变化的,因此并不是所有的字符编码之间的转换都是有意义的。怎么理解这句话呢?比如GBK编码的“中国”转成UTF-8字符编码后,仅仅是由4个字节变成了6个字节来表示,但其字符表现形式还应该是“中国”,而不应该变成“你好”或者“China”。

以上がPython の文字列と文字エンコーディングの問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PSが荷重を見せ続ける理由は何ですか? PSが荷重を見せ続ける理由は何ですか? Apr 06, 2025 pm 06:39 PM

PSの「読み込み」の問題は、リソースアクセスまたは処理の問題によって引き起こされます。ハードディスクの読み取り速度は遅いか悪いです。CrystaldiskInfoを使用して、ハードディスクの健康を確認し、問題のあるハードディスクを置き換えます。不十分なメモリ:高解像度の画像と複雑な層処理に対するPSのニーズを満たすためのメモリをアップグレードします。グラフィックカードドライバーは時代遅れまたは破損しています:ドライバーを更新して、PSとグラフィックスカードの間の通信を最適化します。ファイルパスが長すぎるか、ファイル名に特殊文字があります。短いパスを使用して特殊文字を避けます。 PS独自の問題:PSインストーラーを再インストールまたは修理します。

PSが開始されたときにロードの問題を解決する方法は? PSが開始されたときにロードの問題を解決する方法は? Apr 06, 2025 pm 06:36 PM

ブートがさまざまな理由によって引き起こされる可能性がある場合、「読み込み」に巻き込まれたPS:腐敗したプラグインまたは競合するプラグインを無効にします。破損した構成ファイルの削除または名前変更。不十分なプログラムを閉じたり、メモリをアップグレードしたりして、メモリが不十分であることを避けます。ソリッドステートドライブにアップグレードして、ハードドライブの読み取りをスピードアップします。 PSを再インストールして、破損したシステムファイルまたはインストールパッケージの問題を修復します。エラーログ分析の起動プロセス中にエラー情報を表示します。

PSがファイルを開いたときにロードの問題を解決する方法は? PSがファイルを開いたときにロードの問題を解決する方法は? Apr 06, 2025 pm 06:33 PM

「ロード」は、PSでファイルを開くときに発生します。理由には、ファイルが大きすぎるか破損しているか、メモリが不十分で、ハードディスクの速度が遅い、グラフィックカードドライバーの問題、PSバージョンまたはプラグインの競合が含まれます。ソリューションは、ファイルのサイズと整合性を確認し、メモリの増加、ハードディスクのアップグレード、グラフィックカードドライバーの更新、不審なプラグインをアンインストールまたは無効にし、PSを再インストールします。この問題は、PSパフォーマンス設定を徐々にチェックして使用し、優れたファイル管理習慣を開発することにより、効果的に解決できます。

インストール後にMySQLの使用方法 インストール後にMySQLの使用方法 Apr 08, 2025 am 11:48 AM

この記事では、MySQLデータベースの操作を紹介します。まず、MySQLWorkBenchやコマンドラインクライアントなど、MySQLクライアントをインストールする必要があります。 1. mysql-uroot-pコマンドを使用してサーバーに接続し、ルートアカウントパスワードでログインします。 2。CreatedAtaBaseを使用してデータベースを作成し、データベースを選択します。 3. createTableを使用してテーブルを作成し、フィールドとデータ型を定義します。 4. INSERTINTOを使用してデータを挿入し、データをクエリし、更新することでデータを更新し、削除してデータを削除します。これらの手順を習得することによってのみ、一般的な問題に対処することを学び、データベースのパフォーマンスを最適化することでMySQLを効率的に使用できます。

PSフェザーリングは、遷移の柔らかさをどのように制御しますか? PSフェザーリングは、遷移の柔らかさをどのように制御しますか? Apr 06, 2025 pm 07:33 PM

羽毛の鍵は、その漸進的な性質を理解することです。 PS自体は、勾配曲線を直接制御するオプションを提供しませんが、複数の羽毛、マッチングマスク、および細かい選択により、半径と勾配の柔らかさを柔軟に調整して、自然な遷移効果を実現できます。

mysqlは支払う必要がありますか mysqlは支払う必要がありますか Apr 08, 2025 pm 05:36 PM

MySQLには、無料のコミュニティバージョンと有料エンタープライズバージョンがあります。コミュニティバージョンは無料で使用および変更できますが、サポートは制限されており、安定性要件が低く、技術的な能力が強いアプリケーションに適しています。 Enterprise Editionは、安定した信頼性の高い高性能データベースを必要とするアプリケーションに対する包括的な商業サポートを提供し、サポートの支払いを喜んでいます。バージョンを選択する際に考慮される要因には、アプリケーションの重要性、予算編成、技術スキルが含まれます。完璧なオプションはなく、最も適切なオプションのみであり、特定の状況に応じて慎重に選択する必要があります。

MySQLインストール後にデータベースのパフォーマンスを最適化する方法 MySQLインストール後にデータベースのパフォーマンスを最適化する方法 Apr 08, 2025 am 11:36 AM

MySQLパフォーマンスの最適化は、インストール構成、インデックス作成、クエリの最適化、監視、チューニングの3つの側面から開始する必要があります。 1。インストール後、INNODB_BUFFER_POOL_SIZEパラメーターやclose query_cache_sizeなど、サーバーの構成に従ってmy.cnfファイルを調整する必要があります。 2。過度のインデックスを回避するための適切なインデックスを作成し、説明コマンドを使用して実行計画を分析するなど、クエリステートメントを最適化します。 3. MySQL独自の監視ツール(ShowProcessList、ShowStatus)を使用して、データベースの健康を監視し、定期的にデータベースをバックアップして整理します。これらの手順を継続的に最適化することによってのみ、MySQLデータベースのパフォーマンスを改善できます。

PSフェザーリングをセットアップする方法は? PSフェザーリングをセットアップする方法は? Apr 06, 2025 pm 07:36 PM

PSフェザーリングは、イメージエッジブラー効果であり、エッジエリアのピクセルの加重平均によって達成されます。羽の半径を設定すると、ぼやけの程度を制御でき、値が大きいほどぼやけます。半径の柔軟な調整は、画像とニーズに応じて効果を最適化できます。たとえば、キャラクターの写真を処理する際に詳細を維持するためにより小さな半径を使用し、より大きな半径を使用してアートを処理するときにかすんだ感覚を作成します。ただし、半径が大きすぎるとエッジの詳細を簡単に失う可能性があり、効果が小さすぎると明らかになりません。羽毛効果は画像解像度の影響を受け、画像の理解と効果の把握に従って調整する必要があります。

See all articles