2012-10-29 30 views
6

Tôi đang sử dụng mô-đun OptParse để truy lục giá trị chuỗi. OptParse only supports str typed strings, không phải unicode.Làm cách nào để có thể truy xuất các chuỗi có ký tự không phải ASCII bằng OptParse?

Vì vậy, chúng ta hãy nói rằng tôi bắt đầu kịch bản của tôi với:

./someScript --some-option ééééé 

nhân vật Pháp, chẳng hạn như 'é', được đánh máy str, kích hoạt UnicodeDecodeError s khi đọc trong các mã:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 99: ordinal not in range(128) 

tôi chơi xung quanh một chút với chức năng tích hợp unicode, nhưng tôi hoặc bị lỗi hoặc nhân vật biến mất:

>>> unicode('é'); 
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) 
>>> unicode('é', errors='ignore'); 
u'' 

Tôi có thể làm gì để sử dụng OptParse để truy xuất unicode/utf-8 chuỗi không?

CẬP NHẬT:

Dường như chuỗi có thể được lấy ra và in ok, nhưng sau đó tôi cố gắng sử dụng chuỗi với sqlite (sử dụng các mô-đun APSW), và nó cố gắng để chuyển đổi sang unicode bằng cách nào đó với cursor.execute("..."), và sau đó lỗi xảy ra.

Dưới đây là một chương trình mẫu mà gây ra lỗi:

#!/usr/bin/python 
# coding: utf-8 

import os, sys, optparse 
parser = optparse.OptionParser() 
parser.add_option("--some-option") 
(opts, args) = parser.parse_args() 
print unicode(opts.some_option) 
+0

Đối tượng Str chỉ là các cửa hàng byte vì vậy nếu đầu vào là UTF-8, chuỗi sẽ giữ giá trị UTF-8. Lỗi unicode được ném ở đâu? –

+0

Tôi vừa thử nghiệm điều này trên một giao diện điều khiển UTF-8 và optparse hoạt động tốt và trả về ký tự cho bàn điều khiển. Bạn có thể làm rõ nếu lỗi này là trong mã của bạn hoặc trong các optparse? –

+0

Tùy thuộc vào chương trình của bạn trên optparse hoặc bạn đang xây dựng từ đầu? Trong trường hợp đó tôi sẽ giới thiệu gói docopts thay vì optparse. Bạn sẽ thực sự thực sự ngạc nhiên vì nó dễ dàng phân tích cú pháp các đối số cli như thế nào. – Bruce

Trả lời

1

Input được trả lại trong bảng mã giao diện điều khiển, vì vậy dựa trên ví dụ cập nhật của bạn, sử dụng:

print opts.some_option.decode(sys.stdin.encoding) 

unicode(opts.some_option) mặc định để sử dụng ascii như mã hóa.

0

Tôi tin rằng lỗi của bạn có liên quan đến following:

For example, to write Unicode literals including the Euro currency symbol, the ISO-8859-15 encoding can be used, with the Euro symbol having the ordinal value 164. This script will print the value 8364 (the Unicode codepoint corresponding to the Euro symbol) and then exit:

# -*- coding: iso-8859-15 -*- 

currency = u"€" 
print ord(currency) 
3

Bạn có thể giải mã các đối số trước khi xử lý phân tích cú pháp chúng. Lấy ví dụ của bạn:

#!/usr/bin/python 
# coding: utf-8 
import os, sys, optparse 
parser = optparse.OptionParser() 
parser.add_option("--some-option") 

# Decode the command line arguments to unicode 
for i, a in enumerate(sys.argv): 
    sys.argv[i] = a.decode('ISO-8859-15') 

(opts, args) = parser.parse_args() 
print type(opts.some_option), opts.some_option 

Điều này cho phép đầu ra sau đây:

C:\workspace>python file.py --some-option préférer 
<type 'unicode'> préférer 

Tôi đã chọn trang ISO/IEC 8859-15 mã, vì nó có vẻ thích hợp nhất cho bạn. Thích ứng nếu cần.

+0

Để tránh mã hóa mã hóa, bạn có thể thử đoán nó như sau: '' locale.getpreferredencoding() '' (nhập '' locale''). – Stan

+0

Bằng cách này, bạn có thể cần phải làm cho nó unicode với '' unicode (a.decode ("your_encoding_here")) ''. – Stan

0
#!/usr/bin/python 
# coding: utf-8 

import os, sys, optparse 

reload(sys) 
sys.setdefaultencoding('utf-8') 

parser = optparse.OptionParser() 
parser.add_option(u"--some-option") 
(opts, args) = parser.parse_args() 
print opts.print_help() 
+0

Điều này dường như không hiệu quả đối với tôi. Bạn đang sử dụng python 2 hay 3? Tôi đang chạy python 2.7. –

Các vấn đề liên quan