2016/11/29

[py]buffer()とbytearray()の違いはなんだろう?

よくわからないまま、どこかからコピーしたコードを使うことがしばしばある。
それによって、これってなんだろう?という疑問が湧くこともしばしば。

 

いま、paho-mqttでpublish()するところを見ていたのだが、こんな書き方をしていた。

publish(topic, buffer(data1) + bytearray(data2))

なんとなく、buffer()もbytearray()も似たようなことをしてくれそうだ。
何が違うのだろう?

 

以前、16進数の配列を作る際に、こういうやり方があることを知った。

cmd = bytearray([0x03, 0x12, 0x34, 0x56])

これだと、cmd[1]などで数値が取ってこれるので、そのままif文や添字として使える。
bytearrayは組み込み型で、バイト配列を返すシーケンスとのこと。

 

一方、bufferは毛色がなんか違う。
bufferオブジェクト、なのだ。
CのAPIを使うときなどに出てくるようなので、素のバイト配列なのだろう。

 

data1 = 15
data2 = '1234abcd'.decode('hex')

buf = buffer(chr(data1)) + buffer(data2)
print 'buf=', buf.encode('hex')

dat1 = ord(buf[0])
dat2 = buf[1:]
print 'dat1=', dat1
print 'dat2=', dat2.encode('hex')

buf= 0f1234abcd
dat1= 15
dat2= 1234abcd

data1 = 15
data2 = '1234abcd'.decode('hex')

buf = bytearray(chr(data1)) + bytearray(data2)
print 'buf=', str(buf).encode('hex')

dat1 = buf[0]
dat2 = buf[1:]
print 'dat1=', dat1
print 'dat2=', str(dat2).encode('hex')

buf= 0f1234abcd
dat1= 15
dat2= 1234abcd

 

bytearrayはencode('hex')がないし、str型ではないからstr()で囲んだり、ord()が不要だったりという違いがある。

 

data1 = 15
data2 = '1234abcd'.decode('hex')

buf = buffer(chr(data1)) + bytearray(data2)
print 'buf=', buf.encode('hex')

dat1 = ord(buf[0])
dat2 = buf[1:]
print 'dat1=', dat1
print 'dat2=', dat2.encode('hex')

buf= 0f1234abcd
dat1= 15
dat2= 1234abcd

混合できて、その場合はstr型と同じ扱いになるようだ。

 

paho-mqttのpublish()は、payloadとして文字列を使いたいようだ。
intとか送りたかったらstruct.pack()してくれ、と書いているし。
bytearray型を引数にして使えているのだが、これはpahoがstr()で囲んだりしてくれているからかもしれん。

・・・と思ったが、違った。
bufferを与えると例外が発生したのだ。

TypeError: payload must be a string, bytearray, int, float or None.

bytearrayは許可してたのね。。。
そしてintはstruct.pack()してくれ、だと思ったのだけど、例外の内容を見るとintも許可しているような感じだな。
まあ、使わないから調べないけど。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。