2012-09-07 95 views
3

在CPython的,這個工程:PyPy:獲得原料訪問字符串

import ctypes 
ctypes.pythonapi.PyString_AsString.argtypes = (ctypes.c_void_p,) 
ctypes.pythonapi.PyString_AsString.restype = ctypes.POINTER(ctypes.c_char) 

s = "abc" 
cs = ctypes.pythonapi.PyString_AsString(id(s)) 
cs[0] = "x" 

print s # will print 'xbc' 

在PyPy,它不會因爲我不能這樣訪問C-API。

有沒有辦法在PyPy中做同樣的事情?

+1

只是檢查:你不使用這個東西在真正的代碼,對吧? – JBernardo

+0

只是黑客/嘗試。因此,這應該在CPython中真正保存/保持穩定。有了這個,你可以做有趣的黑客攻擊,比如[this](https://github.com/albertz/playground/blob/master/test_importearlyexit.py)。 :) – Albert

+2

對於無辜旁觀者(不是O.P. :-)):如果您需要一個可指定字符的可變字符串,請使用「bytearray」Python對象。 – jsbueno

回答

2

你不應該那樣做。主要原因是PyPy有一個可移動的垃圾收集器,所以指向它內容的指針可能突然開始指向垃圾。另一個原因是我們有很少的選項具有StringAdd(a,b)的結構,其中沒有底層char *可以引用。這些優化默認情況下未啓用,但它們可能很快就會啓用。

+0

是的,這是我的想法。不過,這太遺憾了。那麼,不要說不可變的字符串真的是不可變的,但更多的是,在某些情況下,如果可以使用可變字符串(如代碼對象,請參見[this]),它會很好(或者它會允許很好的hack /可能性) (https://github.com/albertz/playground/blob/master/test_importearlyexit.py)破解)。 – Albert

+0

使用陣列模塊中的數組。請注意,即使您設法在PyPY中修改這樣的字符串,它也不安全,因爲JIT會進行優化,從而給您帶來垃圾。 – fijal