파이썬에서 객체가 바이트와 같은 객체인지 확인하는 적절한 방법은 무엇입니까?
나는 다음을 예상하는 코드를 가지고 있습니다.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 |