2010-08-18 52 views
2

我讀儘管Python代碼庫,而我被這句話難倒:%d在struct.pack中表示什麼?

struct.pack("<ii%ds"%len(value), ParameterTypes.String, len(value), value.encode("UTF8")) 

我明白了一切,但%d,我不知道爲什麼的value長度被裝在兩次。根據我的理解,該結構將有小端編碼(<),並將包含兩個整數(ii),後跟%d,後跟一個字符串(s)。

%d是什麼意思?

+0

聲明本身就是** BUGGY *。看到我的答案。哪個庫? - ) – 2010-08-18 13:01:02

+0

這是一個函數庫,用於處理通過網絡發送的消息。 – 2010-08-18 13:13:43

回答

1

這是一個普通的string format正被用於創建結構格式

嘗試閱讀它開始作爲一個普通的字符串(忘記struct的時刻)...

"<ii%ds" % len(value)

如果例如,可迭代值的長度是4,那麼字符串將是<ii4s。這隨後被傳遞到struct.pack準備收拾兩個整數,然後長度的字符串從value迭代

+0

謝謝!我不熟悉python,所以我沒有意識到你可以像這樣格式化字符串。 – 2010-08-18 10:00:26

+0

@Matt艾倫:請找一個教程。 – 2010-08-18 10:08:41

+0

@Brendan:-1;看到我的答案。 – 2010-08-18 13:02:19

0

%d四個字節表示這部作品在兩個步驟。

步驟1.

"<ii%ds"%len(value) 

創建的"<ii...some number...s"結構體的格式串。

步驟2.

所得格式串被施加到它的用於指定的len(value)字符的字符串(value)是那些兩個整數之後將被包裝的三個值

ParameterTypes.String, len(value), value.encode("UTF8") 
+0

-1查看我的回答。 – 2010-08-18 13:02:56

+0

-1。不要以爲;調查。沒有數字意味着數字默認爲1.趨向於正確包裝?也許你認爲struct.pack(「s」,foo)的工作方式與「%s」%foo相同?它不; docs say「」「對於's'格式字符,計數被解釋爲字符串的大小,而不是像其他格式字符一樣重複計數;例如,'10s'表示單個10字節字符串,而'10c'表示10個字符。對於打包,字符串被截斷或用適當的空字節填充以使其合適。「」「」 – 2010-08-18 22:02:30

+0

@John Machin:因爲我修改了我的答案,所以我不確定這個問題還是有關係的,但是謝謝你指出了我的錯誤 – 2010-08-18 22:45:06

0

如果,例如,value包含"boo"那麼pack的實際格式說明符將是"<ii3s"

0

%d的意義在於,它是一個字符串格式化參數:
String Formatting Operations

當碎裂開來,"<ii%ds" % len(value)是有點更容易理解。它將正確替換返回值爲len(value)的字符串中的%d轉換指示符。

>>> str = "<ii%ds" 
>>> str % 5 
'<ii5s' 
>>> str % 3 
'<ii3s' 
2

Aarrrgh真不可思議....

@美國洛特:「」「我不認爲這個數字就顯得尤爲重要,因爲Python將趨於正確包裝離不開它。」」 「-1。不要以爲;調查。沒有數字意味着數字默認爲1.趨向於正確包裝?也許你認爲struct.pack("s", foo)的工作方式與"%s" % foo相同?它不; docs say「」「對於's'格式字符,計數被解釋爲字符串的大小,而不是像其他格式字符一樣重複計數;例如,'10s'表示單個10字節字符串, 。而「10C」是指10個字符的包裝,該字符串是截取或用空字節適當填充以使其適合「」」

@Brendan:-1value不是一個數組(不管是什麼);它顯然是打算成爲一個Unicode字符串... lookee here:value.encode("UTF8")

@Matt Ellen:您引用的代碼行嚴重中斷。如果value中有任何非ASCII字符,數據將會丟失。

讓我們來分析一下:

​​

通過去除第一項

struct.pack("<i%ds"%len(value), len(value), value.encode("UTF8"))

現在讓我們假設valueu'\xff\xff'減少問題的空間,所以len(value)爲2

v8 = value.encode('UTF8')'\xc3\xbf\xc3\xbf'

請注意,len(v8)是4.是便士下降了嗎?

所以,我們現在已經是

struct.pack("<i2s", 2, v8)

被打包爲4個字節,02 00 00 00數2。 4字節的字符串v8被截斷(以「2s」中的長度2)爲長度2。數據丟失。失敗。

正確的方法做的是想大概是:

v8 = value.encode('UTF8') 
struct.pack("<ii%ds" % len(v8), ParameterTypes.String, len(v8), v8) 
+0

謝謝John,這是非常有用的信息。寫這個圖書館的人(我的老闆,* gulp *) – 2010-08-18 13:07:25

相關問題