파이썬에서 객체가 바이트와 같은 객체인지 확인하는 적절한 방법은 무엇입니까?
나는 다음을 예상하는 코드를 가지고 있습니다.str
할 것입니다.bytes
다음과 같은 방법으로:
if isinstance(data, bytes):
data = data.decode()
불행히도, 이것은 다음의 경우에는 작동하지 않습니다.bytearray
개체가 다음 중 하나인지 테스트할 수 있는 더 일반적인 방법이 있습니까?bytes
또는bytearray
아니면 둘 다 확인해야 하나요?아이즈hasattr('decode')
내가 느끼는 것만큼 나쁜가요?
여기서 사용할 수 있는 몇 가지 접근법이 있습니다.
오리 타이핑
Python은 오리 타입이기 때문에 다음과 같이 간단하게 할 수 있습니다(일반적으로 제안되는 방식인 것 같습니다).
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에 따라 테스트됩니다.
불행하게도, python 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'
디코드에 명시적으로 적용할 수 있습니다. 몇 바이트를 할애할 필요가 없는 경우.그 이유는 다음 번에 당신이나 다른 누군가가 소스 코드를 읽을 때, 상황이 더 분명해질 것이기 때문입니다.
여기에는 두 가지 질문이 있는데, 그 질문에 대한 답은 다릅니다.
이 게시물의 제목인 첫 번째 질문은 Python에서 객체가 바이트와 같은 객체인지 확인하는 적절한 방법은 무엇입니까?여기에는 여러 가지 기본 제공 유형이 포함됩니다.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'
그러나 원본 게시물 본문에서 질문은 대신 객체가 디코드()를 지원하는지 여부를 테스트하는 방법에 대한 것으로 보입니다.@이 질문에 대한 위의 답변은 훌륭합니다.모든 바이트와 유사한 개체가 디코드()를 지원하는 것은 아닙니다.
시험은if isinstance(data, bytes)
또는if type(data) == bytes
등은 단순한 ASCII 문자열이 테스트를 통과하는 Python 2에서 작동하지 않습니다! 왜냐하면 저는 Python 2와 Python 3을 모두 사용하기 때문에 이것을 극복하기 위해 다음과 같은 검사를 합니다.
if str(type(data)).find("bytes") != -1: print("It's <bytes>")
좀 못생겼지만, 질문이 요구하는 일을 하고 항상 가장 간단한 방법으로 작동합니다.
오랜만에...이것은 더 짧고, 더 단순하며, 더 "우아한" 것입니다.
if not type(data) == str: print("It's bytes")
언급URL : https://stackoverflow.com/questions/34869889/what-is-the-proper-way-to-determine-if-an-object-is-a-bytes-like-object-in-pytho
'programing' 카테고리의 다른 글
postgres 사용자가 존재하는지 확인하는 방법은 무엇입니까? (0) | 2023.05.22 |
---|---|
피벗 테이블에서 그룹화된 날짜의 날짜 형식 변경 (0) | 2023.05.22 |
내부에 스타일이 작동하지 않습니다.각진 HTML (0) | 2023.05.22 |
메모장에서 XML/HTML을 자동으로 포맷하고 들여쓰기하는 방법++ (0) | 2023.05.22 |
dmp 파일 및 로그 파일에서 Oracle 데이터베이스를 가져오는 방법은 무엇입니까? (0) | 2023.05.22 |