2011-08-08 17 views
8

Python 3k dizeleri ve baytlar arasında kesin bir ayrım getirdiğinden, sys.argv dizisindeki komut satırı argümanları dizeler olarak sunulur. Bazen argümanları bayt olarak, örn. Unix'te herhangi bir karakter kodlamasında bulunması gereken bir yolu geçerken.Python'da bayt olarak sys.argv 3k

Bir örnek görelim. Kısa bir Python 3k programı argv.py aşağıdaki gibidir:

o python3.1 argv.py français olarak yürütüldüğünde
import sys 

print(sys.argv[1]) 
print(b'bytes') 

beklenen üretir çıktı: argüman benim yerel kodlamasında olduğu français olduğunu

français

b'bytes'

Not. python3.1 argv.py `echo français|iconv -t latin1`

Traceback (most recent call last): 
    File "argv.py", line 3, in <module> 
    print(sys.argv[1]) 
    UnicodeEncodeError: 'utf-8' codec can't encode character '\udce7' in position 4: surrogates not allowed 

nasıl komut satırı argümanları üzerinden Python 3k programa ikili veri aktarmak zorundadır: biz farklı kodlamada argüman geçmesi Ancak, bir hatayla elde? Kullanım örneği, başka yerel ayarları kullanan bir kullanıcının dosyasına giden bir yolu iletmektir. Eğer kodlama argüman olarak kullanmak veya bytes(sys.argv[1], 'latin-1') çağrı biliyorsanız,

sys.argv[1].encode() ya:

+1

kodlama sorunu olarak autodetected "UTF-8" olduğunu varsayarak önlemek için Cevapları yanıltmak, bir "python3 argv.py \ echo -ne" \ xff \ x80 \ x00 "\' 'önerdiğini belirtmek isterim. Bu,« komut satırı argümanları üzerinden ikili veriyi geçme »örneğidir. – Nope

cevap

2

bunu yapabilirsiniz.

Her ikisi de, unicode dizesinin bayt temsilini vermelidir.

Varsayılan olarak, Python3 UTF-8 kullanır.

+2

Hayır, Python mutlaka olmaz UTF8 kullanın, bu platforma bağlıdır. –

+2

@Lennart Python 3, varsayılan kodlama olarak UTF-8 kullanır. – JBernardo

+2

Hayır, bu kadar basit değil. Terminaller için varsayılan kodlama mutlaka UTF-8 değildir ve dosya sistemleri için varsayılan kodlama değildir.Ben alıntı "Unixy platformlarda LANG ortam değişkeni ile (ve ayrıca bazı diğer platform özel yerel ayarlarla ilgili ortam değişkenleri ile) ayarlanabilir bir platform bağımlı varsayılan kodlama var. Çoğu durumda, ama hepsi değil, sistem varsayılanı UTF-8'dir, asla bu varsayılana güvenmemelisiniz. " Aslında Windows'ta varsayılan olan cp1252'dir. .py dosyaları için varsayılan olsa da, UTF8'dir. –

8

Hata, UnicodeDecodeError yerine bir UnicodeEncodeError olduğunu unutmayın. Python, komut satırında geçirilen tam baytları korur (PEP 383 surrogateescape hata işleyicisi aracılığıyla), ancak bu baytlar geçerli UTF-8 değildir ve dolayısıyla konsola yazma için kodlanamazlar.

$ python3.2 -c "import os, sys; print(os.fsencode(sys.argv[1]).decode('latin-1'))" `echo français|iconv -t latin1` 
français 

os.fsencode fonksiyonu çağırma:

bu başa çıkmak için en iyi yol aşağıdaki örnek kodda olduğu gibi, uygulama içinde komut satırı bağımsız yeniden yorumlamak için doğru kodlama uygulama düzeyde bilgi kullanmaktır Komut satırı argümanlarını işlerken otomatik olarak uygulanan Python dönüşümünü tersine çevirir. decode('latin-1') yöntem çağırma işlemi, düzgün bir şekilde çözülmüş bir dize almak için doğru dönüşümü gerçekleştirir. Özellikle bu tür sorunların üstesinden gelmek için Python 3.2'de, özellikle Python 3.2'de, os.fsencode eklenmiştir. Python 3.1 için os.fsencode(sys.argv[1]) eşdeğer yapı sys.argv[1].encode(sts.getfilesystemencoding(), 'surrogateescape')

Düzenleme Şubat 2013 geçerli: Python 3.2+ için güncellenmiş, ve Python komut satırı kodlama

+0

Yerel ayarın UTF-8 olduğunu düşünemezsiniz. Bu nedenle, kodlama dosya sistemini kullanarak kodlamak zorundasınız: sys.argv [1] .encode (sys.getfilesystemencoding(), 'surrogateescape') decode ('latin-1') – mhagger

+2

Gerçekten. Her ne kadar Python 3.3'te 'os.fsencode' kullanmak daha da kolay. Ayrıca bir hata yaptım, sys.argv belgelerinin bu noktayı gerçekten açıklaması gerektiğini belirttim. – ncoghlan

İlgili konular