一日一技:怎么你的字符串跟我不一樣
如果你經常使用Python的命令行交互環境,你一定遇到過下面這個現象:
- >>> a = 'test'
- >>> a
- 'test'
- >>> print(a)
- test
首先定義一個變量a,它的值為字符串test。現在,當你在命令行交互環境直接輸入變量名再回車的時候,你看到的是'test',當你輸入print(a)的時候,你看到的卻是test。
直接輸入變量名回車,字符串會被單引號包起來。而使用print函數打印變量,字符串又沒有引號。
如果說引號只是一個小問題的話,再來看看反斜杠會怎么樣:
- >>> b = 'D:\game\pal4'
- >>> b
- 'D:\\game\\pal4'
- >>> print(b)
- D:\game\pal4
在這里,b變量的值為Windows下面的一個文件夾路徑。在定義的時候,我使用的是單根反斜杠。
當我輸入變量名,然后回車時,看到的結果是'D:\\game\\pal4',不僅有最外層的引號,而且反斜杠全部變成了兩根。
但是當我使用print函數打印出來的時候,一切又正常了。
覺得很詭異嗎?
實際上,輸入變量名,回車以后,你看到的才是這個字符串真正的樣子,因為在Python里面是不存在單根反斜杠的。當你要表示反斜杠本身的時候,就應該是\\這種寫法。
當然在定義的時候你可以只寫單根反斜杠,在大多數情況下,Python會理解你的意圖,所以它會自動把單根反斜杠轉換為兩個反斜杠。
而使用print關鍵字打印出來的,是經過Python優化,更便于人類閱讀的樣子。
當然,使用print函數也能看到字符串真正的樣子,不過需要修改一下:
- >>> b = 'D:\game\pal4'
- >>> b
- 'D:\\game\\pal4'
- >>> print(repr(b))
- 'D:\\game\\pal4'
當你使用repr函數先處理字符串,再打印時,它的效果就和直接輸入變量名回車是一樣的了。
在Python中,repr(對象)本質上是調用了對象的__repr__這個方法。而如果直接print(對象),實際上是打印了對象__str__方法返回的內容。我們來做一個實驗:
- class Test:
- def __repr__(self):
- return 'hello world!'
- def __str__(self):
- return '為什么我總是對你說你好,因為你是我的世界啊,傻瓜'
- you = Test()
動手測試一下,輸入you然后直接回車顯示的是什么內容。輸入print(you)顯示的又是什么內容。
運行效果如下圖所示:
從上面的例子可以看出,直接輸入變量名回車和直接用print函數打印調用的是對象的不同方法。所以他們當然可以不一樣。
回到昨天的問題上來。在PyCharm的調試模式中,你看到的內容實際上是變量對象的__repr__方法返回的內容,這里的內容是字符串在Python里面的真正的樣子,所以斜杠會變多。
上面說到,當你輸入Windows路徑的時候,大多數情況下,Python能夠理解你的意圖,把單根反斜杠轉成雙反斜杠。不過也有例外的情況,例如:假設有一個文件夾的名字叫做u6211。它在pal4文件夾里面。那么,路徑應該是:D:\game\pal4\u6211 如果在Python里面執行,會出現什么問題?
- >>> c = 'D:\game\pal4\u6211'
- >>> c
- 'D:\\game\\pal4我'
- >>> print(c)
- D:\game\pal4我
怎么和前面的pal4拼在一起了?因為\u6211是一個Unicode編碼,表示中文我。
這種情況下,你有兩種解決方式:
- 手動使用雙反斜杠:
- >>> b = 'D:\game\pal4\\u6211'
- >>> b
- 'D:\\game\\pal4\\u6211'
- >>> print(b)
- D:\game\pal4\u6211
在定義變量的時候,字符串左側引號的左邊加上字母r:
- >>> b = r'D:\game\pal4\u6211'
- >>> b
- 'D:\\game\\pal4\\u6211'
- >>> print(b)
- D:\game\pal4\u6211
本文轉載自微信公眾號「未聞Code」,可以通過以下二維碼關注。轉載本文請聯系未聞Code公眾號。