파이썬 3 에서이 바이트 객체를 만들려고했습니다.
b'3\r\n'
그래서 나는 명백한 (나를 위해) 시도하고 이상한 행동을 발견했다.
>>> bytes(3) + b'\r\n'
b'\x00\x00\x00\r\n'
분명히:
>>> bytes(10)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
바이트 변환이 왜 이런 식으로 문서를 읽는지에 대한 포인터를 볼 수 없었습니다. 그러나이 파이썬 문제 format
에서 바이트 추가 에 대한 놀라운 메시지를 발견했습니다 ( Python 3 바이트 형식 참조 ).
http://bugs.python.org/issue3982
이것은 bytes (int)와 같은 홀수와 더 잘 상호 작용하지 않습니다.
과:
bytes (int)가 해당 int의 ASCIIfication을 반환하면 훨씬 편리합니다. 그러나 솔직히 말해서이 행동보다 오류가 더 낫습니다. (내가 가진 적이없는이 행동을 원한다면 오히려 “bytes.zeroes (n)”과 같은 클래스 메쏘드가되고 싶다.
이 행동의 출처를 누군가가 설명 할 수 있습니까?
답변
이것이 설계된 방식입니다. 일반적으로 bytes
단일 정수 대신 iterable을 호출하기 때문에 의미가 있습니다 .
>>> bytes([3])
b'\x03'
문서는 다음에 대한 문서 문자열뿐만 아니라 이것을 나타 냅니다 bytes
.
>>> help(bytes)
...
bytes(int) -> bytes object of size given by the parameter initialized with null bytes
답변
파이썬 3.2에서 할 수있는 일
>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'
https://docs.python.org/3/library/stdtypes.html#int.to_bytes
def int_to_bytes(x: int) -> bytes:
return x.to_bytes((x.bit_length() + 7) // 8, 'big')
def int_from_bytes(xbytes: bytes) -> int:
return int.from_bytes(xbytes, 'big')
따라서, x == int_from_bytes(int_to_bytes(x))
. 이 인코딩은 부호없는 (음이 아닌) 정수에 대해서만 작동합니다.
답변
구조체의 팩을 사용할 수 있습니다 :
In [11]: struct.pack(">I", 1)
Out[11]: '\x00\x00\x00\x01'
“>”는 바이트 순서 (빅 엔디안) 이고 “I”는 형식 문자 입니다. 따라서 다른 작업을 수행하려는 경우 구체적으로 지정할 수 있습니다.
In [12]: struct.pack("<H", 1)
Out[12]: '\x01\x00'
In [13]: struct.pack("B", 1)
Out[13]: '\x01'
이것은 파이썬 2와 파이썬 3 모두에서 동일하게 작동합니다. .
참고 : unpack을 사용 하여 역 연산 (바이트에서 int)을 수행 할 수 있습니다 .
답변
Python 3.5 이상에서는 printf
바이트에 대한 % 보간 ( -style 형식)을 도입했습니다 .
>>> b'%d\r\n' % 3
b'3\r\n'
PEP 0461-바이트 및 바이트 배열에 % 서식 추가를 참조하십시오 .
이전 버전에서는 다음 str
과 .encode('ascii')
같은 결과를 사용할 수있었습니다 .
>>> s = '%d\r\n' % 3
>>> s.encode('ascii')
b'3\r\n'
참고 : 그것은 생산 하는 것과int.to_bytes
다릅니다 :
>>> n = 3
>>> n.to_bytes((n.bit_length() + 7) // 8, 'big') or b'\0'
b'\x03'
>>> b'3' == b'\x33' != '\x03'
True
답변
설명서는 다음과 같이 말합니다.
bytes(int) -> bytes object of size given by the parameter
initialized with null bytes
순서 :
b'3\r\n'
문자 ‘3’(십진 51) 문자 ‘\ r'(13) 및 ‘\ n'(10)입니다.
따라서 다음과 같은 방식으로 처리합니다.
>>> bytes([51, 13, 10])
b'3\r\n'
>>> bytes('3', 'utf8') + b'\r\n'
b'3\r\n'
>>> n = 3
>>> bytes(str(n), 'ascii') + b'\r\n'
b'3\r\n'
IPython 1.1.0 및 Python 3.2.3에서 테스트
답변
3의 ASCIIfication은 "\x33"
아닙니다 "\x03"
!
그것은 파이썬이하는 일 str(3)
이지만 바이너리 데이터의 배열로 간주되고 문자열로 남용되지 않아야하기 때문에 바이트에는 완전히 잘못되었습니다.
원하는 것을 얻는 가장 쉬운 방법 bytes((3,))
은입니다 bytes([3])
.리스트를 초기화하는 것이 훨씬 비싸기 때문에 튜플을 사용할 수있을 때리스트를 사용하지 마십시오. 을 사용하여 더 큰 정수를 변환 할 수 있습니다 int.to_bytes(3, "little")
.
주어진 길이로 바이트를 초기화하는 것은 의미가 있으며 가장 유용합니다. 종종 주어진 크기의 메모리가 필요한 일부 버퍼 유형을 만드는 데 사용되기 때문입니다. 배열을 초기화하거나 0을 써서 파일을 확장 할 때 종종 이것을 사용합니다.
답변
int
(Python2 포함 long
)는 bytes
다음 함수 를 사용하여 변환 할 수 있습니다 .
import codecs
def int2bytes(i):
hex_value = '{0:x}'.format(i)
# make length of hex_value a multiple of two
hex_value = '0' * (len(hex_value) % 2) + hex_value
return codecs.decode(hex_value, 'hex_codec')
역변환은 다른 방법으로 수행 할 수 있습니다.
import codecs
import six # should be installed via 'pip install six'
long = six.integer_types[-1]
def bytes2int(b):
return long(codecs.encode(b, 'hex_codec'), 16)
두 함수는 Python2와 Python3 모두에서 작동합니다.