예상 str
하지만 bytes
다음과 같은 방식 으로 전달되는 경우를 처리하는 코드 가 있습니다 .
if isinstance(data, bytes):
data = data.decode()
안타깝게도 bytearray
. 객체가 bytes
또는 인지 여부를 테스트하는보다 일반적인 방법이 bytearray
있습니까? 아니면 둘 다 확인해야합니까? 가 hasattr('decode')
내가 될 것이라고 느낌으로 나쁜로?
답변
여기에서 사용할 수있는 몇 가지 접근 방식이 있습니다.
오리 타이핑
Python은 duck typed 이므로 다음과 같이 간단하게 수행 할 수 있습니다 (일반적으로 제안되는 방식 인 것 같습니다).
try:
data = data.decode()
except (UnicodeDecodeError, AttributeError):
pass
hasattr
그러나 설명대로 사용할 수 있으며 아마도 괜찮을 것입니다. 물론 이것은 .decode()
주어진 객체에 대한 메서드가 문자열을 반환하고 불쾌한 부작용이 없다고 가정합니다 .
개인적으로 예외 나 hasattr
방법을 권장 하지만 사용하는 것은 귀하에게 달려 있습니다.
str () 사용
이 방법은 흔하지 않지만 가능합니다.
data = str(data, "utf-8")
다른 인코딩은 버퍼 프로토콜의 .decode()
. 세 번째 매개 변수를 전달하여 오류 처리를 지정할 수도 있습니다.
단일 배포 일반 함수 (Python 3.4 이상)
Python 3.4 이상에는 functools.singledispatch 를 통해 단일 배포 제네릭 함수라는 멋진 기능이 포함되어 있습니다. 이것은 좀 더 장황하지만 더 분명합니다.
def func(data):
# This is the generic implementation
data = data.decode()
...
@func.register(str)
def _(data):
# data will already be a string
...
원하는 경우 bytearray
및 bytes
개체에 대한 특수 처리기를 만들 수도 있습니다 .
주의 : 단일 디스패치 함수는 첫 번째 인수에서만 작동합니다! 이것은 의도적 인 기능 입니다. PEP 433을 참조하십시오 .
답변
당신이 사용할 수있는:
isinstance(data, (bytes, bytearray))
다른 기본 클래스로 인해 여기에 사용됩니다.
>>> bytes.__base__
<type 'basestring'>
>>> bytearray.__base__
<type 'object'>
확인하다 bytes
>>> by = bytes()
>>> isinstance(by, basestring)
True
하나,
>>> buf = bytearray()
>>> isinstance(buf, basestring)
False
위 코드는 python 2.7에서 테스트되었습니다.
불행히도 파이썬 3.4에서는 동일합니다 ….
>>> bytes.__base__
<class 'object'>
>>> bytearray.__base__
<class 'object'>
답변
>>> content = b"hello"
>>> text = "hello"
>>> type(content)
<class 'bytes'>
>>> type(text)
<class 'str'>
>>> type(text) is str
True
>>> type(content) is bytes
True
답변
이 코드는 우리가 모르는 것을 알지 않는 한 정확하지 않습니다.
if isinstance(data, bytes):
data = data.decode()
의 인코딩을 모르는 것처럼 보입니다 data
. 당신은 그것이 UTF-8 이라고 가정 하고 있지만 그것은 매우 잘못되었을 수 있습니다. 인코딩을 모르기 때문에 텍스트가 없습니다 . 태양 아래에서 어떤 의미를 가질 수있는 바이트가 있습니다.
좋은 소식은 대부분의 임의의 바이트 시퀀스가 유효한 UTF-8이 아니므로 이것이 중단되면 errors='strict'
조용히 잘못된 작업을 수행하는 대신 크게 중단됩니다 ( 기본값). 짝수 더 좋은 소식은 유효한 UTF-8로 발생하는 임의 시퀀스의 대부분은 또한 (유효한 ASCII, 있다는 것입니다 거의 ) 모든 사람이 어쨌든 구문 분석하는 방법에 동의합니다.
나쁜 소식은이 문제를 해결할 합리적인 방법이 없다는 것입니다. 인코딩 정보를 제공하는 표준 방법이 있습니다. str
대신 bytes
. 일부 타사 코드가 추가 컨텍스트 또는 정보없이 bytes
또는 bytearray
객체를 전달한 경우 유일한 올바른 조치는 실패입니다.
이제 인코딩을 알고 있다고 가정하면 functools.singledispatch
여기에서 사용할 수 있습니다.
@functools.singledispatch
def foo(data, other_arguments, ...):
raise TypeError('Unknown type: '+repr(type(data)))
@foo.register(str)
def _(data, other_arguments, ...):
# data is a str
@foo.register(bytes)
@foo.register(bytearray)
def _(data, other_arguments, ...):
data = data.decode('encoding')
# explicit is better than implicit; don't leave the encoding out for UTF-8
return foo(data, other_arguments, ...)
이것은 메서드에서 작동하지 않으며 data
첫 번째 인수 여야합니다. 이러한 제한 사항이 효과가 없으면 대신 다른 답변 중 하나를 사용하십시오.
답변
해결하려는 내용에 따라 다릅니다. 두 경우를 모두 문자열로 변환하는 동일한 코드를 사용하려면 bytes
먼저 유형을 먼저 변환 한 다음 디코딩하면됩니다. 이렇게하면 한 줄짜리가됩니다.
#!python3
b1 = b'123456'
b2 = bytearray(b'123456')
print(type(b1))
print(type(b2))
s1 = bytes(b1).decode('utf-8')
s2 = bytes(b2).decode('utf-8')
print(s1)
print(s2)
이런 식으로 답은 다음과 같습니다.
data = bytes(data).decode()
어쨌든 'utf-8'
몇 바이트를 절약하지 않으려면 디코딩에 명시 적 으로 작성하는 것이 좋습니다 . 그 이유는 다음에 당신이나 다른 사람이 소스 코드를 읽을 때 상황이 더 분명해질 것이기 때문입니다.
답변
여기에는 두 가지 질문이 있으며 그에 대한 답변은 다릅니다.
첫 번째 질문 인이 게시물의 제목은 파이썬에서 객체가 바이트와 같은 객체인지 결정하는 적절한 방법 은 무엇입니까?입니다. 이 유형의 내장의 숫자를 포함 ( bytes
, bytearray
, array.array
, memoryview
, 등?) 가능성이 또한 사용자 정의 형식. 내가 아는 가장 좋은 방법은 이것들을 확인하는 memoryview
것입니다.
>>> memoryview(b"foo")
<memory at 0x7f7c43a70888>
>>> memoryview(u"foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: memoryview: a bytes-like object is required, not 'str'
그러나 원본 게시물의 본문에서는 객체가 decode ()를 지원하는지 여부 를 어떻게 테스트합니까? 라는 질문처럼 들립니다 . 이 질문에 대한 @ elizabeth-myers의 위 답변은 훌륭합니다. 모든 바이트 열류 객체가 decode ()를 지원하는 것은 아닙니다.
답변
test if isinstance(data, bytes)
또는 if type(data) == bytes
등은 Python 2에서 작동하지 않습니다. 간단한 ASCII 문자열이! Python 2와 Python 3을 모두 사용하기 때문에이를 극복하기 위해 다음 검사를 수행합니다.
if str(type(data)).find("bytes") != -1: print("It's <bytes>")
약간 못 생겼지 만 질문이 요구 하는 작업을 수행 하고 항상 가장 간단한 방법으로 작동합니다.