2013-04-01 14 views
10

Używam prosty skrypt Pythona aby uzyskać wyniki rezerwacji na moim CID: simple.py:Python: UnicodeEncodeError kiedy używam grep

data = {"minorRev":"current minorRev #","cid":"xxx","apiKey":"xxx","customerIpAddress":" ","creationDateStart":"03/31/2013","} 

url = 'http://someservice/services/rs/'      
req = requests.get(url,params=data)       
print req                 
print req.text                 
print req.status_code 

Teraz na wierszu poleceń, jeśli robię python simple.py działa doskonale i drukuje req.text zmienną

jednak gdy próbuję zrobić
python simple.py | grep pattern

mam
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 1314: ordinal not in range(128)

+0

Patrz: http://stackoverflow.com/questions/2596714/why-does-python-print-unicode-characters -when-the-default-encoding-is-ascii –

+1

przeczytać przez [this] (http://stackoverflow.com/questions/1473577/writing-unicode-strings-via-sys-stdout-in-python). Zasadniczo, podczas wyprowadzania wyniku, 'sys.stdout.encoding == None' – shx2

Odpowiedz

18

printpotrzeby zakodować ciąg przed wysłaniem do stdout, ale gdy proces jest w rurze, wartość sys.stdout.encoding jest None, więc print odbiera obiekt unicode a następnie próbuje zakodować ten obiekt przy użyciu kodeka ascii - jeśli masz znaki spoza ASCII w tym obiekcie unicode, zostanie zgłoszony wyjątek.

Możesz rozwiązać ten problem, kodując wszystkie unicode obiekty przed wysyłając je na standardowe wyjście (ale musisz zgadnąć, który kodek użyć). Zobacz te przykłady:

pliku wrong.py:

# coding: utf-8 

print u'Álvaro' 

Wynik:

[email protected]:/tmp 
$ python wrong.py 
Álvaro 
[email protected]:/tmp 
$ python wrong.py | grep a 
Traceback (most recent call last): 
    File "wrong.py", line 3, in <module> 
    print u'Álvaro' 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc1' in position 0: ordinal not in range(128) 

pliku right.py:

# coding: utf-8 

print u'Álvaro'.encode('utf-8') 
# unicode object encoded == `str` in Python 2 

Wynik:

[email protected]:/tmp 
$ python right.py 
Álvaro 
[email protected]:/tmp 
$ python right.py | grep a 
Álvaro 
3

Jeśli sys.stdout.isatty() ma wartość false (wynik jest przekierowywany do pliku/potoku), a następnie skonfiguruj PYTHONIOENCODING envvar poza swoim skryptem. zawsze drukować Unicode, nie hardcode kodowanie znaków środowiska wewnątrz skryptu:

$ PYTHONIOENCODING=utf-8 python simple.py | grep pattern 
Powiązane problemy