2014-09-05 82 views
6

我今天被一個字符串比較弄糊塗了:看起來python重用字符串(這是一個明智的做法,因爲它們是不可變的)。爲了檢查這個事實,我做了以下事情:python如何做字符串魔術?

>>> a = 'xxx' 
>>> b = 'xxx' 
>>> a == b 
True 
>>> a is b 
True 
>>> id(a) 
140141339783816 
>>> id(b) 
140141339783816 
>>> c = 'x' * 3 
>>> id(c) 
140141339783816 
>>> d = ''.join(['x', 'x', 'x']) 
>>> id(d) 
140141339704576 

這有點令人驚訝。一些問題:

  • 在定義新字符串時,python是否檢查其字符串表的全部內容?
  • 字符串大小是否有限制?
  • 這種機制是如何工作的(比較字符串的散列?)
  • 雖然它似乎並不適用於所有類型的生成字符串。這裏的規則是什麼?
+0

'is'測試的身份,即存儲位置。 '=='測試相等性。這是不明智的交替使用它們,因爲一些字符串,整數等被優化的名稱 – inspectorG4dget 2014-09-05 04:43:31

+0

謝謝,但我已經知道(我沒有詢問任何有關它)。我的問題不是關於'is'還是'==':它關於內部python如何重用字符串。也就是說,關於python用來決定一個字符串不需要添加到其字符串表的內部實現,但它可以被重用。正如你在我的例子中看到的那樣,這個機制並不適用於所有相同的字符串,所以我想了解它何時以及如何使用它。 – dangonfast 2014-09-05 04:51:36

+4

您可能感興趣的內容[Martijn Pieters說的](https://www.codementor.io/python-tutorial/stack-overflow-martijn-pieters-python-optimization?utf-xml:utm_source = reddit-content&utm_medium = blog&utm_term = python-tutorial-python-internals&utm_content = blog&utm_campaign = reddit-content) – inspectorG4dget 2014-09-05 04:55:49

回答

0

由於這個問題有一些upvotes(雖然它是一個重複的有點),我會在這裏回答我原來的問題(感謝上述評論):

  1. 是,蟒蛇檢查全部內容的內部表:但只適用於一些字符串,大部分也可以用作標識符。這個想法是python解釋器(編譯器?)用於標識符處理的加速技巧對於通用字符串處理也很有用。這個過程被稱爲實習
  2. 據我所知是沒有限制字符串大小,但也有其他規則的字符串被重複使用(主要是:他們必須像蟒蛇標識符)
  3. 是,表是一個普通的python字典,並且這些字符串具有用於查找的散列值。
  4. 它僅用於字符串文字和常量表達式。基本上,對於python解釋器在編譯階段可以推斷出的所有東西。

爲了澄清最後一點,以下片段在所有情況下都會對字符串'xxx'進行評估,但他們對於實習有不同的處理方式。

這是一個常量表達式:

'x' * 3 

但是,這並不:

a = 'x' 
a * 3 # this is no constant expression, so no interning can be applied. 

這是毫無表情:

''.join(['x', 'x', 'x']) # this is no expression (a function is called) 
+0

這個答案只會增加混亂。 ''x'* 3'是**不是**字符串,它是一個表達式。結果無論如何都是一個實現細節,一個由編譯器完成的優化,在編譯時預先計算諸如「1 + 1」或「x'* 3」的簡單表達式。在字符串的情況下,通常會使用看起來像標識符的字符串。在交互式提示符下輸入的表達式與'.py'文件完全相同的編譯運行路徑。 – user4815162342 2014-09-05 09:00:05

+0

@ user4815162342:那麼你如何解釋'a ='x'; a * 3'沒有被攔截?這也是一個表達式,並且由此產生的字符串滿足實習內容的所有要求... – dangonfast 2014-09-05 09:19:56

+0

它也是一個表達式,但不是隻涉及常量的表達式。目前的CPython編譯器不夠巧妙,無法證明'a * 3'在這種情況下與''x'* 3'相同。 (實際上,常量的編譯時摺疊是編譯器的一個相對較新的特性,如果內存爲我服務,那麼在2.3-2.5的時間範圍內實現。) – user4815162342 2014-09-05 09:28:59