2009-12-30 4 views
9

question을보고 있었는데 print이 실제로 무엇을하는지 궁금해하기 시작했습니다.python print() 함수는 실제로 무엇을합니까?

string.decode()string.encode()을 사용하여 파이썬 대화 형 셸에서 유니 코드 문자열을 인쇄와 동일한 형식으로 가져 오는 방법을 결코 찾지 못했습니다. 아무리 내가 뭘, 나도

  1. UnicodeEncodeError 또는 얻을
  2. \ "X ##"표기법 이스케이프 된 문자열 ...

이 파이썬 2.x에서,하지만 난 이미 내 방법을 수선하고 실제로 전화를하려고 print() :

예 :

>>> import sys 
>>> a = '\xAA\xBB\xCC' 
>>> print(a) 
ª»Ì 
>>> a.encode(sys.stdout.encoding) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xaa in position 0: ordinal not in range(128) 
>>> a.decode(sys.stdout.encoding) 
u'\xaa\xbb\xcc' 

수정 :

왜 내가이 질문을합니까? 나는 병이 들며 encode() 오류에 지쳐 있고 print이 (적어도 대화 형 셸에서는)이를 수행 할 수 있기 때문에 깨달았다. I합니다 ... 마술 인코딩을 어디에서 사용할 수있는 정보를 발굴하여 올바르게를 인코딩 할 수있는 방법해야 함을 알고

정보 추가 : 내가 파이썬 2.4.3을 실행하는거야

>>> sys.stdin.encoding 
'ISO-8859-1' 
>>> sys.stdout.encoding 
'ISO-8859-1' 

에서 동시

에 (1 9 월 3 2009 15시 37분 12초) GCC 4.1.2 20,080,704 (레드햇 4.1.2-46)은 그러나, 결과 파이썬 2.6과 동일하다. 2 (r262 : 71600, 2009 년 9 월 8 일, 13시 6 분 43 초) 같은 리눅스 상자에.

+2

는 당신이 우리에게 당신이 뭘하려의 예를 들어 줄 수 참조하십시오, 당신이 원하는 무엇을/얻을 것으로 예상, 당신은 무엇을 가지고? 우리가 당신을 더 잘 돕도록 도울 것입니다. –

+2

질문은 파이썬 2 또는 3과 관련이 있습니까? –

+0

그는 "print function"에 대해 말했기 때문에 아마도 파이썬 3 일 것입니다. –

답변

9

편집 : 대답에 내 첫 번째 시도에서

첫째, : (나는 우분투 상자에 파이썬 2.6.4를 사용하고이 편집 및 이전 사이의 주요 변경 ... 있습니다.) , 나는 printstr에 관한 일반적인 정보를 제공해 주었고이 질문에 대해서는 print이라는 간단한 문제가있는 사람들의 이익을 위해 아래에 남겨 두었습니다. OP에서 경험 한 문제를 다루는 새로운 시도에 관해서는 ... 기본적으로 나는 여기에 은색 탄환이 없다고 말하는 경향이 있습니다. print이라면 이상하게 생긴 문자열 리터럴을 이해할 수 있다면 재현 할 수없는 행동입니다 . 내 터미널 창에서 파이썬 다음과 같은 재미있는 상호 작용에 의해 결론을 주도하고 있습니다 :

>>> print '\xaa\xbb\xcc' 
�� 

당신은 터미널에서 직접 입력 ª»Ì를 시도? 인코딩으로 UTF-8을 사용하여 리눅스 터미널에서이 실제로 다음 decode 방법의 도움으로 세 개의 유니 코드 문자처럼 보이도록 할 수있는 6 바이트로 읽어 :

>>> 'ª»Ì' 
'\xc2\xaa\xc2\xbb\xc3\x8c' 
>>> 'ª»Ì'.decode(sys.stdin.encoding) 
u'\xaa\xbb\xcc' 

그래서, '\xaa\xbb\xcc' 리터럴은 을 라틴어 -1 리터럴으로 디코딩하면 이해할 수 있습니다. (글쎄, 실제로 관련 문자의 라틴어 -1과 일치하는 다른 인코딩을 사용할 수 있습니다). 귀하의 경우에만 print에 대해 '그냥 일하고', 확실히 나를 위해하지 않습니다 - 위에서 언급 한 바와 같이.즉 "asdf"보다는 u"asdf" - - 결과 문자열이 일부 비 유니 코드 인코딩을 사용합니다

이 작업은 문자열 리터럴 u로 시작하지를 사용하는 경우는 사실에 의해 설명된다. 아니; 실제로 문자열 개체 자체는 인코딩을 인식하지 못하게 될 것이므로 올바른 값인 x에 대해 인코딩 된 x로 인코딩 된 것처럼 처리해야합니다. 이 기본 개념은 다음 날 리드 :

a = '\xAA\xBB\xCC' 
a.decode('latin1') 
# result: u'\xAA\xBB\xCC' 
print(a.decode('latin1')) 
# output: ª»Ì 

참고 디코딩 오류의 부족 (I 다른 상자에 적절한 유지 될 것으로 예상) 적절한 출력. 분명히 문자열 리터럴은 파이썬에 의해 이해 될 수 있지만, 도움이되는 것은 아닙니다.

이 정보가 도움이됩니까? (적어도 ...하지 않을 경우 상황이 인코딩의 취급 어떤 쉽게 만드는, 어떻게 작동하는지 이해)


이제 몇 가지 설명 값 (희망)와 약간의 재미 비트에 대한! 이것은 나를 위해 잘 작동합니다 :

유니 코드 관련 예외가 발생합니다. 이론적으로 말하자면 첫 번째 디코드는 주어진 문자열에있는 문자를 결정하는 데 필요하므로 의미가 있습니다. 첫 번째로 분명히 알 수있는 것은 바이트입니다. - 파이썬 3 아이디어 (유니 코드) 문자열 글자와 바이트가 잘 들어 맞다면, 바이트는 갑자기 적당하다), 출력은 출력이 출력 스트림의 인코딩을 따르도록 필요하다. (예상대로 이제이

sys.stdout.write("ąöî\n".decode(sys.stdin.encoding).encode(sys.stdout.encoding)) 

는 작동하지만 문자는

ord('ą'.decode('utf-8').encode('latin2')) 

올바른 177을 반환 ... 또한, 실제로 키보드에서 오는 그래서 실제로 표준 입력 인코딩으로 인코딩되어 내 '\ xc4 \ x85 '.encode ('latin2 ')는'\ xc4 \ x85 '의 의미를 파악하는 방법에 대한 단서가 없으므로 입력 코드화는 utf-8입니다. 'ascii'코드는 할 수있는 최선의 방법입니다.


원래 답 : (버전 2.6.4에 대한) 파이썬 문서의

The relevant bitprint(obj)str(obj)에 의해 주어진 문자열을 출력하기위한 것입니다 있다고 말한다. 그렇다면 unicode (unicode(str(obj))에서와 같이)에서 유니 코드 문자열을 얻으려면이 코드를 감쌀 수 있습니다. 그렇지 않으면 파이썬 3을 사용하여이 특수한 귀찮은 코드를 다른 코드로 교환 할 수 있습니다. ;-)

은 또한, 본 당신이 개체에 str 호출의 결과를 조작 할 수있는 것처럼 물체를 보내고 print의 결과를 조작 할 수 있음을 나타내며, 즉 __str__ 방법 장난하는 것이다. 예 : print의 실제 구현에 관해서는

class Foo(object): 
    def __str__(self): 
     return "I'm a Foo!" 

print Foo() 

, 나는이 전혀 유용하지 않을 것으로 예상하지만, 당신이 정말로은 무슨 일이 일어나고 있는지 알고 싶어 경우 ... 그것은에서 파일 Python/bltinmodule.c에 있어요 파이썬 소스 (2.6.4 버전을보고있다). builtin_print으로 시작하는 줄을 찾으십시오. 실제로는 아주 간단합니다. 거기에서 진행되는 마법은 없습니다.:-)

잘하면이 답변을 귀하의 질문에 ...하지만 당신이 내가 완전히 누락 된 더 이상한 문제가 있다면, 코멘트를, 나는 두 번째 시도를 할거야. 또한 파이썬 2.x를 다루고 있다고 가정하고 있습니다. 그렇지 않으면 나는 유용한 코멘트가 없을 것이라고 생각한다.

+0

불행히도 builtin_print는 2.4의 해당 파일에 없습니다. http://svn.python.org/view/python/branches/release24-maint/Python/bltinmodule.c?view=markup – Kimvais

+0

그 당시의 이유는 'print'는 여전히 문법적인데, 함수로 동작시키기 위해서는'builtin_print'가 필요합니다. 또한 stdin에서 오는 문자열을 디코딩 할 때'sys.stdin.encoding' 대신'sys.stdin.encoding'을 사용하기를 원할 것입니다. stdout.encoding' - 오늘의 전형적인 박스에서 모두 똑같은 반응을 보입니다. –

+0

음, 나는 마지막으로 답을 수정 한 후 작업을 명확히하기를 희망합니다. 인코딩 문제를 피하기 위해 할 수있다. 나는 낙관적이지 않다. 어쨌든, 그것이 무엇인가를 명확하게하는지 궁금하다 ... 그리고 그 질문 자체에 새로운 코멘트가 첨부되어있다. 나는 "학문적 관심 "여기에 참여했다. (나는 이것을 재미있는 태그 BTW에 추가하고있다. ;-)) –

5

print()sys.stdout.encoding을 사용하여 출력 콘솔에서 이해할 수있는 내용을 확인한 다음 str.encode()을 호출 할 때이 인코딩을 사용합니다. 당신 look at the source, 그것은 다음 sys.stdout을 얻고 경우

[편집] 호출

PyFile_WriteObject(PyTuple_GetItem(args, i), file, 
       Py_PRINT_RAW); 

같아요 마법 Py_PRINT_RAW에 있지만 the source 그냥 말한다 : 그래서 마법 여기

if (flags & Py_PRINT_RAW) { 
    value = PyObject_Str(v); 
    } 

. sys.stdout.write(str(item))으로 인수를 반복하면 트릭을 수행해야합니다. 모든 print 여기하고있다

+0

중요한 미묘함을 없애기 위해 +1 내 대답에 완전히 빠졌습니다. –

+0

이것이 맞을 수도 있지만 내 질문에 대답하지 않는 것 같습니다. 분명히 print()는 결국 str.encode (sys.stdout.encoding)가 실패하기 때문에 마술을하는 sys.stdout.write()를 호출합니다. – Kimvais

+2

@Kimvais : 나는 소스를 찾았습니다. 마술은 없다. –

2
>>> import sys 
>>> a = '\xAA\xBB\xCC' 
>>> print(a) 
ª»Ì 

sys.stdout 원시 바이트을 쓰고있다. a 문자열은 유니 코드 문자가 아닌 바이트 문자열입니다.

왜 내가이 질문을합니까? 나는 encode() 에러에 질리고 아팠다. 그리고 print가 그것을 할 수 있다는 것을 깨달았다. (최소한 대화 형 쉘에서). 나는

없는 아아

print 여기에서 모든 마법 아무것도 없습니다 ... (가) 마술 정보를 어디에서 사용하는 인코딩을 파고에 의해, 올바르게 인코딩을 할 수있는 방법되어야한다는 것을 알고있다. 몇 바이트를 넘겨 주면 바이트를 stdout으로 덤프합니다.

.encode().decode()을 올바르게 사용하려면 바이트와 문자의 차이를 이해해야하며 사용할 올바른 인코딩을 알아 내야합니다.

0
import sys 

source_file_encoding = 'latin-1' # if there is no -*- coding: ... -*- line 

a = '\xaa\xbb\xcc' # raw bytes that represent string in source_file_encoding 

# print bytes, my terminal tries to interpret it as 'utf-8' 
sys.stdout.write(a+'\n') 
# -> �� 

ua = a.decode(source_file_encoding) 
sys.stdout.write(ua.encode(sys.stdout.encoding)+'\n') 
# -> ª»Ì 

Defining Python Source Code Encodings

관련 문제