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


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_typesix.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.