在《詳解Python拼接字符串的七種方式》這篇推文裏,我提到過,字符串是程序員離不開的事情。後來,我看到了一個英文版本的說法:html
There are few guarantees in life: death, taxes, and programmers needing to deal with strings.
它居然把程序員處理字符串跟死亡大事並列了,可見這是多麼命中註定......python
回頭看其它文章,我發現這種說法獲得了佐證,由於我在無心中已零零碎碎地說起了字符串的不少方面,例如:字符串讀寫文件、字符串打印、字符串不可變性、字符串Intern機制、字符串拼接、是否會取消字符串,等等。而這些,還只能算字符串面目的冰山一角。git
既然如此,那乾脆再單獨寫寫Python的字符串吧。這篇內容可能會很基(li)礎(lun),並非什麼「騷操做」或「冷知識」,權當是一份溫故而求知新的筆記。程序員
根據維基百科定義:字符串是由零個或多個字符組成的有限序列。而在Python 3中,它有着更明確的意思:字符串是由Unicode碼點組成的不可變序列(Strings are immutable sequences of Unicode code points.)github
字符串是一種序列,這意味着它具有序列類型都支持的操做:編程
# 如下的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。那麼,怎麼用這個二進制數字,來表示人類的文化性的字符呢?這些字符數量龐大,並且還在日益增加與變化,什麼樣的編碼方案纔是最靠譜的呢?app
歷史上,人類創造了多種多樣的字符編碼標準,例如ASCII(1963年)編碼,以西歐語言的字符爲主,它的缺點是隻能編碼128個字符;例如GB2312(1981年),這是中國推出的編碼標準,在兼容ASCII標準的基礎上,還加入了對日文、俄文等字符的編碼,但缺點還是編碼範圍有限,沒法表示古漢語、繁體字及更多書寫系統的字符。
Unicode編碼標準於1991年推出,至今迭代到了第11版,已經可以編碼146個書寫系統的130000個字符,可謂是無所不包,真不愧是「國際碼」。Unicode編碼實際上是一個二進制字符集,它創建了從書寫字符映射成惟一的數字字符的關係,可是,因爲各系統平臺對字符的理解差別,以及出於節省空間的考慮,Unicode編碼還須要再作一次轉換,轉換後的新的二進制數字才能做爲實際存儲及網絡傳輸時的編碼。
這種轉換方式被稱爲Unicode轉換格式(Unicode Transformation Format,簡稱爲UTF),它又細分爲UTF-八、UTF-1六、UTF-32等等方式。咱們最經常使用的是UTF-8。爲何UTF-8最經常使用呢?由於它是可變長度的編碼方案,針對不一樣的字符使用不一樣的字節數來編碼,例如編碼英文字母時,只須要一個字節(8個比特),而編碼較複雜的漢字時,就會用到三個字節(24個比特)。
二進制的編碼串能夠說是給機器閱讀的,爲了方便,咱們一般會將其轉化爲十六進制,例如「中」字的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已成大勢所趨,因此我就再也不對此作介紹或比對了。
雖然不提縱向版本間的差別,可是,我想將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貓】,後臺回覆「愛學習」,免費得到20+本精選電子書。
拓展閱讀:
https://zh.wikipedia.org/wiki...
https://zh.wikipedia.org/wiki...