2013-08-24 13 views
11

Wpadłem w niecodzienną sytuację. Próbuję skryptu interaktywnej konsoli (dla celów dydaktycznych/testowanie), a ja próbowałem następujące:Skąd pochodzi interaktywny monit Pythona ">>>"?

$ python > /dev/null 
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr 9 2012, 20:52:43) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> print 3 
>>> 

3 nie jest drukowana, tak wyraźnie wszystko inne było na stderr. Jak na razie dobrze. Ale potem przekierować stderr:

$ python 2> /dev/null 
>>> print 3 
3 
>>> 

Jak monit być drukowane w obu przypadkach?

EDYCJA: Przekierowanie zarówno stdout jak i stderr nie powoduje absolutnie nic do wydrukowania. Tak więc Python wyraźnie "wybiera" jedną z stdout lub . Czy to udokumentowane? Nie mogłem zrozumieć, jak to się dzieje w kodzie źródłowym Pythona.

+2

Huh, to dziwne. Być może sprawdza "isatty"? – delnan

+0

To byłby mój domysł, ale nie mogę się domyślić, gdzie Python to robi. Najdziwniejszą rzeczą jest to, że 'PyOS_StdioReadline', funkcja, która wydaje się być odpowiedzialna za czytanie danych wejściowych, jest zakodowana na stałe, aby wydrukować monit na' stderr'. Jeśli 'stderr' zostanie przekierowany na' stdout', jak sugeruje drugi przykład, powinniśmy zobaczyć baner. – nneonneo

+1

Łatwiej byłoby użyć narzędzia zaprojektowanego do nauczania Pythona, np. [Funkcja notebooka w ipython] (http://ipython.org/notebook.html). –

Odpowiedz

4

Wydaje się kontroli Pythona czy stdout jest tty:

/* This is needed to handle the unlikely case that the 
* interpreter is in interactive mode *and* stdin/out are not 
* a tty. This can happen, for example if python is run like 
* this: python -i < test1.py 
*/ 
if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout))) 
    rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt); 
else 
    rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, 
             prompt); 

źródłowego z Parser/myreadline.c wokół linii 194.

Jest możliwe, że interpreter importuje moduł readline przy starcie, w którym to przypadku PyOS_ReadlineFunctionPointer będzie ustaw na call_readline, która korzysta z biblioteki readline. W szczególności wywołuje rl_callback_handler_install. Dokumentacja tej funkcji nie określa miejsca drukowania monitu, ale możliwe jest, że sprawdza, czy są one ustawione.

+0

Jednak powyżej wydaje się, że ustawię 'PyOS_ReadlineFunctionPointer' na' PyOS_StdioReadline' (z wyjątkiem VMS, którego zdecydowanie nie ma na liście). – nneonneo

+0

@nneonneo Tak, jestem trochę zakłopotany, ale to jedyne odniesienie, które mogę znaleźć, które może w jakiś sposób wyjaśnić zachowanie, które widzisz. Czy masz dostęp do biblioteki readline? Ponieważ na początku pliku wspomina, że ​​używa go, gdy jest dostępny. – Bakuriu

+0

@nneonneo Ustawia go tylko wtedy, gdy nie ma wartości "NULL". Jeśli interpreter zaimportuje 'readline' podczas uruchamiania, moduł' readline' ustawi jego funkcję (zobacz funkcję init w 'Modules/readline.c'), a zatem' PyOS_Readline' nie użyje 'PyOS_StdioReadline'. – Bakuriu

Powiązane problemy