首頁 系統教程 Linux Python 程式設計的歷史演變

Python 程式設計的歷史演變

Jan 01, 2024 am 09:31 AM
linux linux教程 紅帽 linux系統 linux指令 linux認證 紅帽linux linux視頻

導讀 一旦走上了程式設計之路,如果你不把編碼問題搞清楚,那麼它將像幽靈一般糾纏你整個職業生涯,各種靈異事件會接踵而來,揮之不去。只有充分發揮程式設計師死磕到底的精神你才有可能徹底擺脫編碼問題帶來的煩惱。

我第一次遇到編碼問題是寫 JavaWeb 相關的項目,一串字元從瀏覽器遊離到應用程式程式碼中,翻江倒海沉浸到資料庫中,隨時隨地都有可能踩到編碼的地雷。第二次遇到程式設計問題就是學Python 的時候,在爬取網頁資料時,程式設計問題又出現了,當時我的心情是崩潰的,用時下最ing的一句話就是:「我當時就懵逼了」。

為了搞清字元編碼,我們得從計算機的起源開始,計算機中的所有數據,不論是文字、圖片、視頻、還是音頻文件,本質上最終都是按照類似 01010101 的數字形式存儲的。我們是幸運的,我們也是不幸的,幸運的是時代賦予了我們都有機會接觸計算機,不幸的是,計算機不是我們國人發明的,所以計算機的標準得按美帝國人的習慣來設計,那麼最開始計算機是透過什麼樣的方式來表現字元的呢?這要從電腦編碼的發展史說起。

ASCII

每個做 JavaWeb 開發的新手都會遇到亂碼問題,每個做 Python 爬蟲的新手都會遇到編碼問題,為什麼編碼問題那麼蛋痛呢?這個問題要從1992年 Guido van Rossum 創造 Python 這門語言說起,那時的 Guido 絕對沒想到的是 Python 這門語言在今天會如此受大家歡迎,也不會想到電腦發展速度會如此驚人。 Guido 在當初設計這門語言時是不需要關心編碼的,因為在英語世界裡,字符的個數非常有限,26個字母(大小寫)、10個數字、標點符號、控制符,也就是鍵盤上所有的鍵所對應的字元加起來也不過是一百多個字元而已。這在電腦中用一個位元組的儲存空間來表示一個字元是綽綽有餘的,因為一個位元組相當於8個位元位,8個位元位元可以表示256個符號。於是聰明的美國人就制定了一套字元編碼的標準叫ASCII(American Standard Code for Information Interchange),每個字元都對應唯一的一個數字,例如字元A 對應的二進制數值是01000001,對應的十進位就是65 。最開始ASCII 只定義了128 個字符編碼,包括96 個文字和32 個控制符號,總共128 個字符,只需要一個字節的7 位就能表示所有的字符,因此ASCII 只使用了一個字節的後7位,最高位都為0。
Python 编码的前世今生

EASCII (ISO/8859-1)

然而電腦慢慢地普及到其他西歐地區時,他們發現還有很多西歐所特有的字元是ASCII 編碼表中沒有的,於是後來出現了可擴展的ASCII 叫EASCII ,顧名思義,它是在ASCII的基礎上擴展而來,把原來的7 位擴充到8 位,它完全相容於ASCII,擴展出來的符號包括表格符號、計算符號、希臘字母和特殊的拉丁符號。然而EASCII 時代是一個混亂的時代,大家沒有統一標準,他們各自把最高位元按照自己的標準實現了自己的一套字元編碼標準,比較著名的就有 CP437, CP437 是Windows 系統中使用的字元編碼,如下圖:
Python 编码的前世今生
另外一種被廣泛使用的EASCII 還有 ISO/8859-1(Latin-1),它是國際標準化組織(ISO)及國際電工委員會(IEC)共同製定的一系列8位字符集的標準,ISO/8859-1 只繼承了CP437 字符編碼的128-159 之間的字符,所以它是從160 開始定義的,不幸的是這些眾多的ASCII 擴充字集之間互不相容。
Python 编码的前世今生

GBK

隨著時代的進步,電腦開始普及到千家萬戶,比爾蓋茲讓每個人桌面都有一台電腦的夢想得以實現。但是電腦進入中國不得不面臨的一個問題就是字元編碼,雖然咱們國家的漢字是​​人類使用頻率最多的文字,漢字博大精深,常見的漢字就有成千上萬,這已經大大超出了ASCII 編碼所能表示的字元範圍了,即使是EASCII 也顯得杯水車薪,於是聰明的中國人自己弄了一套編碼叫 GB2312,又稱GB0,1981由中國國家標準總局發布。 GB2312 編碼共收錄了6763個漢字,同時它也相容於 ASCII。 GB2312 的出現,基本上滿足了漢字的電腦處理需要,它所收錄的漢字已經覆蓋中國大陸 99.75% 的使用頻率。不過 GB2312 還是無法 100% 滿足中國漢字的需求,對一些罕見的字和繁體字 GB2312 沒法處理,後來就在 GB2312 的基礎上創建了一種叫 GBK 的編碼。 GBK 不僅收錄了 27484 個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。同樣 GBK 也是相容於 ASCII 編碼的,對於英文字元以 1 個位元組來表示,漢字用兩個位元組來識別。

Unicode

對於如何處理中國人自己的文字我們可以另立山頭,按照我們自己的需求制定一套編碼規範,但是計算機不止是美國人和中國人用啊,還有歐洲、亞洲其他國家的文字諸如日文、韓文全世界各地的文字加起來估計也有好幾十萬,這已經大大超出了ASCII 碼甚至GBK 所能表示的範圍了,況且人家為什麼用採用你GBK 標準呢?如此龐大的字元庫究竟用什麼方式來表示好呢?於是統一聯盟國際組織提出了 Unicode 編碼,Unicode 的學名是“Universal Multiple-Octet Coded Character Set”,簡稱為UCS。
Python 编码的前世今生
Unicode 有兩種格式:UCS-2 和 UCS-4。 UCS-2 就是用兩個字節編碼,一共16 個比特位,這樣理論上最多可以表示65536個字符,不過要表示全世界所有的字符顯然65536 個數字還遠遠不夠,因為光漢字就有近10 萬個,因此Unicode 4.0 規範定義了一組附加的字元編碼,UCS-4 就是用4 個位元組(實際上只用了31 位,最高位元必須為0)。
Unicode 理論上完全可以涵蓋所有語言所使用的符號。世界上任何一個字元都可以用一個 Unicode 編碼來表示,一旦字元的 Unicode 編碼確定下來後,就不會再改變了。但是Unicode 有一定的局限性,一個Unicode 字元在網路上傳輸或最終儲存起來的時候,並不見得每個字元都需要兩個字節,例如一字元「 A “,用一個位元組就可以表示的字符,偏偏還要用兩個字節,顯然太浪費空間了。第二問題是,一個Unicode 字元是儲存到電腦裡面時就是一串01 數字,那麼電腦怎麼知道一個2 位元組的Unicode 字元是表示一個2 位元組的字元呢,還是表示兩個1 位元組的字元呢,如果你不事先告訴計算機,那麼計算機也會懵逼了。 Unicode 只是規定如何編碼,並沒有規定如何傳輸、儲存這個編碼。例如 「漢」 字的 Unicode 編碼是 6C49,我可以用 4 個 ASCII 數字來傳送、儲存這個編碼;也可以用 UTF-8 編碼的 3 個連續的位元組 E6 B1 89 來表示它。關鍵在於通信雙方都要認可。因此 Unicode 編碼有不同的實作方式,例如:UTF-8、UTF-16 等等。這裡的Unicode 就像英文一樣,做為國與國之間交流世界通用的標準,每個國家有自己的語言,他們把標準的英文文檔翻譯成自己國家的文字,這是實現方式,就像UTF- 8。

UTF-8

UTF-8(Unicode Transformation Format)作為 Unicode 的一種實現方式,廣泛應用於互聯網,它是一種變長的字元編碼,可以根據具體情況用 1-4 個位元組來表示一個字元。例如英文字元這些原本就可以用 ASCII 碼表示的字元用 UTF-8 表示時就只需要一個位元組的空間,和 ASCII 是一樣的。對於多位元組(n 個位元組)的字符,第一個位元組的前 n 為都設為 1,第 n 1 位元設為 0,後面位元組的前兩個位元都設為 10。剩下的二進位位元全部用該字元的 UNICODE 碼填滿。
Python 编码的前世今生
以漢字「好」為例,「好」對應的Unicode 是597D,對應的區間是0000 0800 -- 0000 FFFF,因此它用UTF-8 表示時需要用3 個位元組來存儲,597D 用二進位表示是: 0101100101111101 ,填入1110xxxx 10xxxxxx 10xxxxxx 得到11100101 10100101 10111101,轉換成16 進位:E5A5BD ,因此「好編碼」的對應程式的「Uni」50A4m

中文 好
unicode 0101 100101 111101
編碼規則 1110xxxx 10xxxxxx 10xxxxxx
# --------------------------
utf-8 11100101 10100101 10111101
--------------------------
16進位utf-8 e 5 a 5 b d Python 字元編碼

現在總算把理論說完了。再來談談 Python 中的編碼問題。 Python 的出生時間比 Unicode 早很多,Python 的預設編碼是ASCII。
>>> import sys
# >>> sys.getdefaultencoding()

'ascii'

所以在 Python 原始碼檔案中如果不明確地指定編碼的話,就會出現語法錯誤

#test.py
登入後複製

print "你好" 上面是 test.py 腳本,運行

python test.py
登入後複製
就會包如下錯誤:

File “test.py”, line 1 yntaxError: Non-ASCII character ‘/xe4′ in file test.py on line 1, but no encoding declared;
登入後複製
為了在原始程式碼中支援非 ASCII 字符,必須在原始檔案的第一行或第二行顯示地指定編碼格式:

# coding=utf-8
登入後複製
或是:

#!/usr/bin/python
# -*- coding: utf-8 -*-
登入後複製
在Python 中和字串相關的資料類型,分別是 str、unicode 兩種,他們都是basestring 的子類,可見str 與unicode 是兩種不同類型的字串物件。

    basestring
      /  / 
     /    /
   str    unicode
登入後複製
對於同一個漢字“好”,用str 表示時,它對應的就是UTF-8 編碼'/xe5/xa5/xbd',而用 Unicode 表示時,它對應的符號就是u'/u597d',與u "好"是等同的。需要補充一點的是,str 類型的字元其具體的編碼格式是 UTF-8 還是 GBK,還是其它格式,根據作業系統相關。例如在 Windows 系統中,cmd 命令列中顯示的:

# windows终端
>>> a = '好'
>>> type(a)
<type 'str'>
>>> a
'/xba/xc3'
登入後複製
而在 Linux 系統的命令列中顯示的是:

# linux终端
>>> a='好'
>>> type(a)
<type 'str'>
>>> a
'/xe5/xa5/xbd'

>>> b=u'好'
>>> type(b)
<type 'unicode'>
>>> b
u'/u597d'
登入後複製
不論是Python3x、Java 還是其他程式語言,Unicode 編碼都成為了語言的預設編碼格式,而資料最後儲存到媒體的時候,不同的媒體可有用不同的方式,有些人喜歡用UTF-8 ,有些人喜歡用GBK,這都無所謂,只要平台統一的編碼規範,具體怎麼實現並不關心。

Python 编码的前世今生

#str 與 unicode 的轉換

那麼在 Python 中 str 和 unicode 之間是如何轉換的呢?這兩種類型的字串類型之間的轉換就是靠這兩個方法:decode 和encode。

Python 编码的前世今生

#

#从str类型转换到unicode
s.decode(encoding)   =====>  <type 'str'> to <type 'unicode'>
#从unicode转换到str
u.encode(encoding)   =====>  <type 'unicode'> to <type 'str'>

>>> c = b.encode('utf-8')
>>> type(c)
<type 'str'>
>>> c
'/xe5/xa5/xbd'

>>> d = c.decode('utf-8')
>>> type(d)
<type 'unicode'>
>>> d
u'/u597d'
登入後複製
這個'/xe5/xa5/xbd'就是 Unicode u'好'透過函數 encode 編碼得到的 UTF-8 編碼的 str 類型的字串。反之亦然,str 類型的 c 透過函數 decode 解碼成 Unicode 字串 d。 str(s) 與 unicode(s)

str(s) 和 unicode(s) 是兩個工廠方法,分別傳回 str 字串物件和 Unicode 字串對象,str(s) 是 s.encode(‘ascii’) 的簡寫。實驗:

>>> s3 = u"你好"
>>> s3
u'/u4f60/u597d'
>>> str(s3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
登入後複製
上面s3 是Unicode 類型的字串,str(s3)相當於是執行s3.encode('ascii'),因為「你好」兩個漢字不能用ASCII 碼來表示,所以就報錯了,指定正確的編碼:s3.encode('gbk') 或s3.encode('utf-8') 就不會出現這個問題了。類似的 Unicode 有同樣的錯誤:

>>> s4 = "你好"
>>> unicode(s4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)
>>>
登入後複製
unicode(s4)等效於s4.decode('ascii')
,因此要正確的轉換就要正確指定其編碼 s4.decode('gbk') 或s4.decode('utf-8')。 亂碼

所有出現亂碼的原因都可以歸結為字元經過不同編碼解碼在編碼的過程中使用的編碼格式不一致,例如:

# encoding: utf-8

>>> a='好'
>>> a
'/xe5/xa5/xbd'
>>> b=a.decode("utf-8")
>>> b
u'/u597d'
>>> c=b.encode("gbk")
>>> c
'/xba/xc3'
>>> print c
登入後複製
UTF-8 編碼的字元'好'佔用3 個位元組,解碼成Unicode 後,如果再用 GBK 來解碼後,只有2 個位元組的長度了,最後出現了亂碼的問題,因此防止亂碼的最好方法就是始終堅持使用同一種編碼格式對字元進行編碼和解碼操作。

Python 编码的前世今生

#其他技巧

對於如 Unicode 形式的字串(str 類型):

s = 'id/u003d215903184/u0026index/u003d0/u0026st/u003d52/u0026sid'
登入後複製
轉換成真正的 Unicode 需要使用:

s.decode('unicode-escape')
登入後複製
測試:

>>> s = 'id/u003d215903184/u0026index/u003d0/u0026st/u003d52/u0026sid/u003d95000/u0026i'
>>> print(type(s))
<type 'str'>
>>> s = s.decode('unicode-escape')
>>> s
u'id=215903184&index=0&st=52&sid=95000&i'
>>> print(type(s))
<type 'unicode'>
>>>
登入後複製
以上程式碼和概念都是基於 Python2.x。 ###

以上是Python 程式設計的歷史演變的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

vscode終端命令不能用 vscode終端命令不能用 Apr 15, 2025 pm 10:03 PM

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)

See all articles