2013-05-08 13 views
5

Ben şu üç piton komut:partisiydi ve piton boruları arasındaki fark

parent1.py

import subprocess, os, sys 

relpath = os.path.dirname(sys.argv[0]) 
path = os.path.abspath(relpath) 
child = subprocess.Popen([os.path.join(path, 'child.lisp')], stdout = subprocess.PIPE) 
sys.stdin = child.stdout 
inp = sys.stdin.read() 
print(inp.decode()) 

parent2.py:

import sys 
inp = sys.stdin 
print(inp) 

child.py:

print("This text was created in child.py") 

Aşağıdakilerle parent1.py'yi ararsam:

python3 parent1.py 

beklenen aşağıdaki çıkışı gibi bana verir:

This text was created with child.py 

i ile parent2.py ararsanız:

python3 child.py | python3 parent2.py 

i aynı çıktı elde edin. Ama ilk örnekte, child.py'nin çıktısını bayt olarak alıyorum ve ikincisini doğrudan bir dizge olarak alıyorum. Bu neden? Python ve bash boruları arasında sadece bir fark var mı yoksa bunu önlemek için yapabileceğim bir şey var mı?

+0

[Bu deneyin] (http://stackoverflow.com/questions/3999114/linux-pipe-into-python-ncurses-script-: Sen Unicode veri sağlamak için child.stdout boruyu sarmak için bir io.TextIOWrapper() instance kullanabilirsiniz stdin-and-termios? answertab = oy # tab-top) – scott

cevap

3

Python stdin ve stdout'u açtığı zaman, hangi kodlamanın kullanıldığını algılar ve size unicode dizeleri vermek için text I/O kullanır.

Ancak subprocess başlattığınız alt işlemin kodlamasını algılamaz (ve gerçekleştiremez), bu nedenle bayt döndürür.

sys.stdin = io.TextIOWrapper(child.stdout, encoding='utf8') 
+2

Evet. OS'de sadece bir tür boru olduğunu ve bash ve Python tarafından da aynı şekilde kullanıldığını eklemek isterim. Bir akımın yorumu farklı olabilir ve Python iki durumu birbirinden ayırır; Birinde giriş, bayt olarak, diğeri ise string/unicode olarak yorumlanır. – Alfe

+0

Çalıştıran teşekkürler. Şimdi bir şey yapmak istiyorsam 'cat/bin/bash | parent2.py 'bir UnicodeDecodeError yükseltir çünkü sys.stdin.read() byte döndürmez. Bu etrafında dolaşmanın bir yolu var mı? – Kritzefitz

+1

@Alfe: Yine de, her iki durumda da girdiyi bayt olarak kaydeder, sadece ikinci durumda akışınızı otomatik olarak bir 'TextIOWrapper' içinde sarar. Temel bayt akışına erişebilir veya her iki durumda da kendi sarıcınızı manuel olarak ekleyebilirsiniz. Ama yine de, yararlı bir nokta. – abarnert