문자열이 유니 코드인지 아스키인지 어떻게 확인합니까?


271

문자열에 어떤 인코딩이 있는지 알아 내기 위해 파이썬에서 무엇을해야합니까?


56
유니 코드는 인코딩 이 아닙니다 .
— ulidtko

더 중요한 것은 왜 관심을 가져야합니까?
— Johnsyweb

@Johnsyweb 때문에{UnicodeDecodeError} 'ascii' codec can't decode byte 0xc2
— alex

답변:


295

Python 3에서 모든 문자열은 유니 코드 문자 시퀀스입니다. bytes원시 바이트를 보유 하는 유형이 있습니다.

Python 2에서 문자열은 유형 str이거나 유형일 수 있습니다 unicode. 다음과 같은 코드를 사용하여 알 수 있습니다.

def whatisthis(s):
    if isinstance(s, str):
        print "ordinary string"
    elif isinstance(s, unicode):
        print "unicode string"
    else:
        print "not a string"

이것은 "유니 코드 또는 ASCII"를 구별하지 않습니다. 파이썬 타입 만 구별합니다. 유니 코드 문자열은 ASCII 범위의 순수 문자로 구성 될 수 있으며 바이트 스트링은 ASCII, 인코딩 된 유니 코드 또는 텍스트가 아닌 데이터를 포함 할 수 있습니다.


3
@ProsperousHeart : 아마도 파이썬 3을 사용하고있을 것입니다.
— Greg Hewgill

124

객체가 유니 코드 문자열인지 또는 바이트 문자열인지 확인하는 방법

당신은 사용할 수 있습니다 type또는 isinstance.

파이썬 2에서 :

>>> type(u'abc')  # Python 2 unicode string literal
<type 'unicode'>
>>> type('abc')   # Python 2 byte string literal
<type 'str'>

파이썬 2에서는 str바이트 시퀀스입니다. 파이썬은 인코딩이 무엇인지 모릅니다. unicode유형은 저장 텍스트 안전한 방법입니다. 이것을 더 이해하려면 http://farmdev.com/talks/unicode/를 권장 합니다.

파이썬 3에서 :

>>> type('abc')   # Python 3 unicode string literal
<class 'str'>
>>> type(b'abc')  # Python 3 byte string literal
<class 'bytes'>

Python 3에서는 Python str2와 비슷 unicode하며 텍스트를 저장하는 데 사용됩니다. 무엇 호출 된 str파이썬 2 것은이라고 bytes파이썬 3.


바이트 문자열이 유효한 UTF-8인지 또는 ASCII인지 확인하는 방법

에 전화 할 수 있습니다 decode. UnicodeDecodeError 예외가 발생하면 유효하지 않습니다.

>>> u_umlaut = b'\xc3\x9c'   # UTF-8 representation of the letter 'Ü'
>>> u_umlaut.decode('utf-8')
u'\xdc'
>>> u_umlaut.decode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

당신이해야처럼 str.decode는 파이썬 3에 보이는 존재하지 않습니다 - 그냥 다른 사람의 참조를 위해 unicode(s, "ascii")또는 뭔가
— 그림자

3
죄송합니다.str(s, "ascii")
— Shadow

1
이것은 파이썬 3
— ProsperousHeart에

2
@ProsperousHeart Python 3을 포함하도록 업데이트되었으며 바이트 문자열과 유니 코드 문자열의 차이점을 설명하려고 시도했습니다.
— Mikel

44

python 3.x에서 모든 문자열은 유니 코드 문자 시퀀스입니다. str에 대한 인스턴스 검사 (기본적으로 유니 코드 문자열을 의미 함)를 수행하면 충분합니다.

isinstance(x, str)

파이썬 2.x와 관련하여 대부분의 사람들은 두 가지 검사가있는 if 문을 사용하는 것 같습니다. 하나는 str, 하나는 유니 코드입니다.

하나의 명령문으로 'string-like'객체가 있는지 확인하려면 다음을 수행하십시오.

isinstance(x, basestring)

이것은 거짓입니다. Python 2.7에서는을 isinstance(u"x",basestring)반환합니다 True.
— PythonNut

11
@PythonNut : 이것이 핵심이라고 생각합니다. isinstance (x, basestring)를 사용하면 위의 뚜렷한 이중 테스트를 대체 할 수 있습니다.
— KQ.

5
많은 경우에 유용하지만 질문자가 의미하는 것은 아닙니다.
— mhsmith

3
이것이 질문에 대한 답변입니다. 다른 모든 사람들은 OP가 말한 것을 오해하고 파이썬에서 유형 검사에 대한 일반적인 대답을했습니다.
— fiatjaf

1
OP의 질문에 대답하지 않습니다. 질문의 제목 (단독)은이 답변이 정확하도록 해석 될 수 있습니다. 그러나 OP는 구체적으로 질문의 설명에 "figure out which"를 표시하고 있으며이 답변은이를 설명하지 않습니다.
— MD004

31

Kumar McMillan을 인용하면 유니 코드는 인코딩이 아닙니다.

ASCII, UTF-8 및 기타 바이트 문자열이 "텍스트"인 경우 ...

... 그런 다음 유니 코드는 "텍스트"입니다.

그것은 추상적 인 형태의 텍스트입니다

McMillan의 유니 코드를 읽어보십시오. PyCon 2008의 Python, Completely Demystified 강연 에서는 Stack Overflow에 대한 대부분의 관련 답변보다 훨씬 나은 점을 설명합니다.


이 슬라이드는 아마도 내가 만난 유니 코드에 대한 최고의 소개 일 것입니다.
— Jonny

23

코드의 요구와 호환되는 경우 모두 파이썬이 파이썬 3, 직접 같은 것들을 사용할 수 없습니다 isinstance(s,bytes)또는 isinstance(s,unicode)때문에, 제외 또는 파이썬 버전 테스트 / 하나의 시도에 그들을 배치하지 않고 bytes파이썬 2에 정의되어 있지 및 unicode파이썬 3에서 정의되지 .

추악한 해결 방법이 있습니다. 매우 추악한 것은 유형 자체를 비교하는 대신 유형 이름 을 비교하는 것입니다. 예를 들면 다음과 같습니다.

# convert bytes (python 3) or unicode (python 2) to str
if str(type(s)) == "<class 'bytes'>":
    # only possible in Python 3
    s = s.decode('ascii')  # or  s = str(s)[2:-1]
elif str(type(s)) == "<type 'unicode'>":
    # only possible in Python 2
    s = str(s)

약간 덜 추악한 해결책은 파이썬 버전 번호를 확인하는 것입니다.

if sys.version_info >= (3,0,0):
    # for Python 3
    if isinstance(s, bytes):
        s = s.decode('ascii')  # or  s = str(s)[2:-1]
else:
    # for Python 2
    if isinstance(s, unicode):
        s = str(s)

그것들은 비유 론적이며, 대부분의 경우 더 좋은 방법이있을 것입니다.


6
더 좋은 방법은 아마도 사용하는 것입니다 six, 테스트에 대한 six.binary_type과six.text_type
— 이안 Clelland

1
type (s) .__ name__ 을 사용하여 유형 이름을 조사 할 수 있습니다 .
— Paulo Freitas

논리 오류가 없으면 코드의 유스 케이스를 잘 모르겠습니다. 파이썬 2 코드에는 "not"이 있어야한다고 생각합니다. 그렇지 않으면 Python 3의 경우 모든 것을 유니 코드 문자열로 변환하고 Python 2의 경우에는 반대입니다!
— oligofren

네, 올리 포 프렌, 그것이하는 일입니다. 표준 내부 문자열은 Python 3의 유니 코드이고 Python 2의 ASCII입니다. 따라서 코드 스 니펫은 텍스트를 표준 내부 문자열 유형 (유니 코드 또는 ASCII)으로 변환합니다.
— Dave Burton

12

사용하다:

import six
if isinstance(obj, six.text_type)

6 개의 라이브러리 내에서 다음과 같이 표시됩니다.

if PY3:
    string_types = str,
else:
    string_types = basestring,

2
이어야합니다 if isinstance(obj, six.text_type) . 그러나 그렇습니다. 이것은 정답입니다.
— karantan

OP의 질문에 대답하지 않습니다. 질문의 제목 (단독)은이 답변이 정확하도록 해석 될 수 있습니다. 그러나 OP는 구체적으로 질문의 설명에 "figure out which"를 표시하고 있으며이 답변은이를 설명하지 않습니다.
— MD004

4

파이썬 3에서는 다음과 같이 말하는 것이 공평하지 않습니다.

  • strs는 모든 x에 대한 UTFx입니다 (예 : UTF8)

  • strs는 유니 코드입니다

  • strs는 유니 코드 문자의 순서로 정렬됩니다.

파이썬의 str유형은 (일반적으로) 일련의 유니 코드 코드 포인트이며, 일부는 문자로 매핑됩니다.


Python 3에서도 상상할 수 있듯이이 질문에 대답하는 것은 간단하지 않습니다.

ASCII 호환 문자열을 테스트하는 확실한 방법은 인코딩을 시도하는 것입니다.

"Hello there!".encode("ascii")
#>>> b'Hello there!'

"Hello there... ☃!".encode("ascii")
#>>> Traceback (most recent call last):
#>>>   File "", line 4, in <module>
#>>> UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 15: ordinal not in range(128)

오류는 사례를 구별합니다.

Python 3에는 잘못된 유니 코드 코드 포인트가 포함 된 문자열도 있습니다.

"Hello there!".encode("utf8")
#>>> b'Hello there!'

"\udcc3".encode("utf8")
#>>> Traceback (most recent call last):
#>>>   File "", line 19, in <module>
#>>> UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 0: surrogates not allowed

그것들을 구별하는 동일한 방법이 사용됩니다.


3

이것은 다른 사람에게 도움이 될 수 있습니다. 변수의 문자열 유형에 대한 테스트를 시작했지만 내 응용 프로그램의 경우 단순히 s를 utf-8로 반환하는 것이 더 합리적입니다. return_utf를 호출하는 프로세스는 처리하는 내용을 알고 문자열을 적절하게 처리 할 수 ​​있습니다. 코드는 깨끗하지 않지만 버전 테스트 또는 6 가지 가져 오기없이 Python 버전에 관계없이 사용하려고합니다. 다른 사람들을 돕기 위해 아래 샘플 코드를 개선하여 의견을 말하십시오.

def return_utf(s):
    if isinstance(s, str):
        return s.encode('utf-8')
    if isinstance(s, (int, float, complex)):
        return str(s).encode('utf-8')
    try:
        return s.encode('utf-8')
    except TypeError:
        try:
            return str(s).encode('utf-8')
        except AttributeError:
            return s
    except AttributeError:
        return s
    return s # assume it was already utf-8

당신은 내 친구가 올바른 답변을받을 자격이! 나는 파이썬 3을 사용하고 있으며이 보물을 찾을 때까지 여전히 문제가있었습니다!
— mnsr

2

Universal Encoding Detector를 사용할 수 있지만, 예를 들어 문자열 "abc"의 인코딩을 알 수 없기 때문에 실제 인코딩이 아닌 최상의 추측 만 제공 할 것입니다. 다른 곳에서 인코딩 정보를 가져와야합니다. 예를 들어 HTTP 프로토콜은이를 위해 Content-Type 헤더를 사용합니다.



0

간단한 접근 방법 중 하나 unicode는 내장 함수 인지 확인하는 것 입니다. 그렇다면 Python 2에 있고 문자열은 문자열입니다. 모든 것이 한 unicode가지로 이루어 지려면 :

import builtins

i = 'cats'
if 'unicode' in dir(builtins):     # True in python 2, False in 3
  i = unicode(i)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.