私は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に変換する最良の方法は何ですか?
256未満である限り、chr(somenumber)
を使用してintの1バイト値を取得します。pySerialはそれを正常に送信します。
PySerialを介して送信する場合、very標準ライブラリのstructモジュールを参照することをお勧めします。必要と思われるほぼすべてのデータ型(1バイト以上)のエンコードも同様です。
In Python 2-最初に文字列に変換し、次にユニコードに変換します。
str(integer).decode("utf-8")
最善の方法だと思います。任意の整数で動作しますが、入力として文字列を入力しても動作します。
コメントにより編集を更新:For Python 2 and 3-これは両方で動作しますが、少し面倒です:
str(integer).encode("utf-8").decode("utf-8")
私は、最善の解決策は明示的であり、数字をバイトとして表現すること(および 文字としてではない )を言うことだと思う:
>>> 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でコードを実行しても驚くことはありません。また、意図がより明確で明確になります。
代わりに 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'
_
上記の例では、たとえば、ネットワークバイト順で符号なし整数に整数をパックします。