web-dev-qa-db-ja.com

int値をUnicodeに変換します

私はpyserialを使用しており、255未満の値を送信する必要があります。int自体を送信すると、intのascii値が送信されます。だから今、私はintをUnicode値に変換し、シリアルポート経由で送信しています。

unichr(numlessthan255);

However it throws this error:
'ascii' codec can't encode character u'\x9a' in position 24: ordinal not in range(128)

IntをUnicodeに変換する最良の方法は何ですか?

20
user2578666

256未満である限り、chr(somenumber)を使用してintの1バイト値を取得します。pySerialはそれを正常に送信します。

PySerialを介して送信する場合、very標準ライブラリのstructモジュールを参照することをお勧めします。必要と思われるほぼすべてのデータ型(1バイト以上)のエンコードも同様です。

15
Steve Barnes

In Python 2-最初に文字列に変換し、次にユニコードに変換します。

str(integer).decode("utf-8")

最善の方法だと思います。任意の整数で動作しますが、入力として文字列を入力しても動作します。

コメントにより編集を更新:For Python 2 and 3-これは両方で動作しますが、少し面倒です:

str(integer).encode("utf-8").decode("utf-8") 
29
chasmani

私は、最善の解決策は明示的であり、数字をバイトとして表現すること(および 文字としてではない )を言うことだと思う:

>>> import struct
>>> struct.pack('B', 128)
>>> '\x80'

これにより、Python 2とPython 3の両方でコードが機能します(Python 3では、結果は bytes オブジェクトになります)。 Python 3では、新しいbytes([128])を使用して値128の単一バイトを作成することもできます。

私はchr()ソリューションの大ファンではありません: Python 3で 、(バイトではなく文字)stringを生成します エンコード を送信する前に(ファイル、ソケット、ターミナルなど)にする必要があります—Python 3のchr()は問題の問題のあるPython 2 unichr()と同等です。 structソリューションには、Pythonのバージョンに関係なく、バイトを正しく生成できるという利点があります。 chr()を使用してシリアルポート経由でデータを送信する場合は、その後に行わなければならないエンコードを制御する必要があります。 Python 3で使用されるデフォルトのエンコードがUTF-8の場合にコードが機能する可能性があります(これは事実だと思います)が、これは256より小さいコードポイントのUnicode文字をUTFで1バイトとしてコーディングできるためです-8。これにより、私が推奨しない微妙で複雑な不要なレイヤーが追加されます(コードの理解が難しくなり、必要に応じてデバッグが難しくなります)。

したがって、上記のアプローチを使用することを強くお勧めします(これはSteve BarnesとMartijn Pietersからも示唆されました):byte(および文字ではありません)。 Python 3でコードを実行しても驚くことはありません。また、意図がより明確で明確になります。

10
Eric O Lebigot

代わりに chr() function を使用してください。 256未満で128を超える値を送信していますが、Unicode文字を作成しています。

次に、Unicode文字をエンコードしてbyte文字を取得する必要があります。このエンコードは、ASCII範囲(0-127):

_>>> str(unichr(169))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa9' in position 0: ordinal not in range(128)
_

これは通常のPython 2の動作です。Unicode文字列をバイト文字列に変換しようとすると、暗黙的なエンコードが行われ、デフォルトのエンコードはASCIIです。

代わりにchr()を使用する場合、1文字のバイト文字列を作成し、暗黙的なエンコードはnotを行う必要があります:

_>>> str(chr(169))
'\xa9'
_

調べたいもう1つの方法は、 struct module です。特に整数値を送信する必要がある場合greater255未満:

_>>> struct.pack('!H', 1000)
'\x03\xe8'
_

上記の例では、たとえば、ネットワークバイト順で符号なし整数に整数をパックします。

10
Martijn Pieters