Szczerze, chciałbym wiedzieć o obu, chociaż nie mam doświadczenia z Python 3. Zaktualizowałem pytanie.
Johanna Larsson,
17
@ S.Lott: pytanie o podstawowe różnice między sys.stdout.write()i print(i / lub dlaczego Python ma oba) jest całkowicie rozsądnym pytaniem i nie wymaga przykładów. OP nie powiedział, że składnia polecenia jest myląca.
smci,
Odpowiedzi:
293
printjest tylko cienkim opakowaniem, które formatuje dane wejściowe (modyfikowalne, ale domyślnie ze spacją między argumentami i znakiem nowej linii na końcu) i wywołuje funkcję zapisu danego obiektu. Domyślnie ten obiekt jest sys.stdout, ale plik można przekazać za pomocą formularza „chevron”. Na przykład:
W Pythonie 2.6+ printwciąż jest instrukcją, ale może być używana jako funkcja z
from __future__ import print_function
Aktualizacja: Bakuriu skomentował, że istnieje niewielka różnica między funkcją print a instrukcją print (a bardziej ogólnie między funkcją a instrukcją).
W przypadku błędu podczas oceny argumentów:
print"something",1/0,"other"#prints only something because 1/0 raise an Exceptionprint("something",1/0,"other")#doesn't print anything. The function is not called
Warto również zauważyć, że printdodaje także nowy wiersz do wszystkiego, co piszesz, co się nie zdarza sys.stdout.write.
Michael Mior,
5
sys.stdout.writeJest także bardziej uniwersalny, jeśli kiedykolwiek będziesz musiał napisać kod podwójnej wersji (np. Kod, który działa jednocześnie z Python 2.x oraz Python 3.x).
andreb
3
@MichaelMior Możesz wyłączyć nowy wiersz, który printprint "this",; print "on the same line as this"
uzupełnia go
1
@ bjd2385 Nie >>jest tutaj operatorem rshift, ale specyficzną formą „chevron” printinstrukcji. Zobacz docs.python.org/2/reference/…
luc
5
sys.stdout.write()buforuje również dane wejściowe i może nie natychmiast opróżnić dane wejściowe do fd. aby upewnić się, że zachowuje się jak funkcja drukowania, należy dodać: sys.stdout.flush()
kerbelp
151
printNajpierw konwertuje obiekt na ciąg (jeśli nie jest to już ciąg). Umieści także spację przed obiektem, jeśli nie jest to początek linii i znak nowej linii na końcu.
Podczas używania stdoutmusisz samodzielnie przekonwertować obiekt na ciąg znaków (na przykład przez wywołanie „str”) i nie ma znaku nowej linii.
+1 za wspomnienie o znaku nowej linii! To jest główna różnica między printi .write(), powiedziałbym.
Eric O Lebigot,
9
UWAGA: printmożna wprowadzić pominięcie nowej linii. W Pythonie 2.x umieść przecinek na końcu, a spacja zostanie wypisana, ale nie będzie nowego wiersza. Np. print 99,W Pythonie 3, print(..., end='')unikniesz dodawania nowej linii (a także unikniesz dodawania spacji, chyba że to zrobisz end=' '.
ToolmakerSteve
40
@EOL Jak zabawne jest to, że ktoś o imieniu EOL komentuje „\ n” ... Rozśmieszyło mnie to. Nie mam życia. Zabij mnie.
Depado
2
to NIE jest prawda, printdziałanie zachowuje się nieco inaczej w procedurach obsługi sygnałów w python2.X, tzn. print nie może być zastąpiony przez sys.stdout w przykładzie: stackoverflow.com/questions/10777610/…
ddzialak
41
Moje pytanie brzmi, czy są sytuacje, w których
sys.stdout.write()lepiej jest
print
Po zakończeniu opracowywania skryptu innego dnia przesłałem go na serwer unix. Wszystkie moje komunikaty debugowania używały printinstrukcji, które nie pojawiają się w dzienniku serwera.
Jest to przypadek, w którym możesz potrzebować sys.stdout.writezamiast tego.
co? Czy na pewno jest to różnica między print()i sys.stdout.write(), w przeciwieństwie do różnicy między stdouti stderr? Do debugowania należy użyć loggingmodułu, na którym drukowane są wiadomości stderr.
ostrokach
1
Ya. To samo dotyczy używania nohupi przekierowywania do .outpliku.
conner.xyz
1
użycie sys.stdout.flush () pomogłoby.
suprit chaudhary
Jeśli używasz nohup, domyślnie całe pisanie do stdouti stderrzostanie przekierowane nohup.out, niezależnie od tego, czy używasz, printczy stdout.write.
Zheng Liu,
40
Oto przykładowy kod oparty na książce Learning Python autorstwa Mark Lutz, który odpowiada na twoje pytanie:
import sys
temp = sys.stdout # store original stdout object for later
sys.stdout = open('log.txt','w')# redirect all prints to this log fileprint("testing123")# nothing appears at interactive promptprint("another line")# again nothing appears. it's written to log file instead
sys.stdout.close()# ordinary file object
sys.stdout = temp # restore print commands to interactive promptprint("back to normal")# this shows up in the interactive prompt
Otwarcie log.txt w edytorze tekstu ujawni następujące informacje:
Czy jest jakiś sposób, aby móc drukować na ekranie, a także zapisywać do pliku?
Devesh Saini
5
@DeveshSaini: Tak, po prostu nadpisuj sys.stdout klasą proxy, która ma co najmniej funkcję write () i flush (). Tutaj napisałem przykładowy fragment .
ponycat
14
Jest co najmniej jedna sytuacja, w której chcesz sys.stdoutzamiast drukować.
Jeśli chcesz zastąpić linię bez przechodzenia do następnej linii, na przykład podczas rysowania paska postępu lub komunikatu o stanie , musisz zapętlić coś takiego jak
Note carriage return->"\rMy Status Message: %s"% progress
A ponieważ print dodaje nowy wiersz, lepiej jest używać sys.stdout.
Jeśli print dodaje nową linię, dlaczego po prostu nie zamiast tego drukuj ('message', end = '')?
Apoorv Patne
8
Moje pytanie brzmi, czy są sytuacje, w których sys.stdout.write()lepiej jestprint
Jeśli piszesz aplikację wiersza polecenia, która może zapisywać zarówno pliki, jak i standardowe wyjście, jest to przydatne. Możesz robić takie rzeczy jak:
def myfunc(outfile=None):if outfile isNone:
out = sys.stdout
else:
out = open(outfile,'w')try:# do some stuff
out.write(mytext +'\n')# ...finally:if outfile isnotNone:
out.close()
Oznacza to, że nie możesz użyć tego with open(outfile, 'w') as out:wzoru, ale czasem warto.
Ściśle mówiąc, to można użyć with- def process(output): # .../ if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)(dodawanie nowych linii w razie potrzeby oczywiście). To na pewno niezbyt czyste, to na pewno.
Pozew Fund Moniki w
4
W wersji 2.x printinstrukcja przetwarza to, co dajesz, przekształcając ją w ciągi po drodze, obsługując separatory i znaki nowej linii oraz umożliwiając przekierowanie do pliku. 3.x zamienia go w funkcję, ale nadal ma te same obowiązki.
sys.stdout jest plikiem lub podobnym do pliku, który ma metody zapisu do niego, które pobierają ciągi lub coś wzdłuż tej linii.
wskazane jest, gdy przydatne jest drukowanie dynamiczne, na przykład w celu dostarczenia informacji w długim procesie:
import time, sys
Iterations=555for k in range(Iterations+1):# some code to execute here ...
percentage = k /Iterations
time_msg ="\rRunning Progress at {0:.2%} ".format(percentage)
sys.stdout.write(time_msg)
sys.stdout.flush()
time.sleep(0.01)
print (time_msg, end = '') zamiast tego sys.stdout.write (time_msg) sys.stdout.flush () również działa
rluts
2
>>> sys.stdout.write(1)Traceback(most recent call last):File"<stdin>", line 1,in<module>TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a");print(1)
a1
Obserwując powyższy przykład:
sys.stdout.writenie napisze obiektu nie łańcuchowego, ale printbędzie
sys.stdout.writenie doda nowego symbolu linii na końcu, ale printzrobi to
Jeśli zanurzymy się głęboko,
sys.stdout to obiekt pliku, którego można użyć do wydruku print ()
jeśli print()nie określono argumentu pliku , sys.stdoutzostanie użyty
Czy istnieją sytuacje, w których sys.stdout.write () jest preferowane do drukowania?
Na przykład pracuję nad małą funkcją, która drukuje gwiazdy w formacie piramidy po przekazaniu liczby jako argumentu, chociaż możesz to zrobić za pomocą end = "", aby wydrukować w osobnej linii, użyłem sys.stdout.write w koordynacji z nadrukiem, aby to zadziałało. Aby rozwinąć tę kwestię, stdout.write drukuje w tej samej linii, gdzie jako print zawsze drukuje jej zawartość w osobnej linii.
import sys
def printstars(count):if count >=1:
i =1while(i <= count):
x=0while(x<i):
sys.stdout.write('*')
x = x+1print('')
i=i+1
printstars(5)
Czy istnieją sytuacje, w których sys.stdout.write () jest preferowane do drukowania?
Przekonałem się, że standardowe wyjście działa lepiej niż drukowanie w sytuacji wielowątkowości. Używam kolejki (FIFO) do przechowywania linii do wydrukowania i trzymam wszystkie wątki przed linią drukowania, aż mój wydruk Q będzie pusty. Mimo to, używając print, czasami tracę końcowy \ n debugowania I / O (używając wing pro IDE).
Kiedy używam std.out z \ n w ciągu, debugowane we / wy formatuje poprawnie, a \ n są dokładnie wyświetlane.
Czy znasz jakiś powód, dla którego stdout powinien działać lepiej niż drukowanie w tym przypadku, czy jest to anegdota? Czy możesz podać minimalny działający przykład, w którym to się dzieje?
user2653663,
Myślę, że standardowe wyjście działa na niższym poziomie niż drukowanie. Zdecydowanie miałem uszkodzenie wątku, ponieważ dwie procedury drukowania walczyły o przejście przez standardowe wyjście. Pisanie na stdout po jednym z każdego wątku usunęło dla mnie zepsucie.
W Pythonie 3 istnieje prawidłowy powód, dla którego warto zastosować print sys.stdout.write, ale ten powód można również zmienić w powód do użyciasys.stdout.write zamiast tego.
Powodem jest to, że teraz print jest funkcją w Pythonie 3, możesz to zmienić. Możesz więc używać print wszędzie w prostym skrypcie i zdecydować, że te instrukcje drukowania muszą pisać w stderrzamian. Teraz możesz po prostu przedefiniować funkcję drukowania, możesz nawet zmienić funkcję drukowania globalną, zmieniając ją za pomocą wbudowanego modułu. Oczywiście, że zfile.write możesz określić, co to jest plik, ale w przypadku nadpisywania wydruku możesz również przedefiniować separator linii lub separator argumentów.
Odwrotnie jest. Być może jesteś absolutnie pewien, że piszesz stdout, ale wiesz również, że zamierzasz zmienić druk na coś innego, z czego możesz zdecydować się skorzystaćsys.stdout.write i użyj print do dziennika błędów lub czegoś innego.
To, czego używasz, zależy od tego, jak zamierzasz go używać. printjest bardziej elastyczny, ale może to być powód do korzystania i nieużywania go. Nadal wybrałbym elastyczność i wybrałbym druk. Innym powodem użycia printzamiast tego jest znajomość. Więcej osób zrozumie teraz, co masz na myśli przez druk, a mniej wie sys.stdout.write.
Jedną z różnic jest to, że podczas próby wydrukowania bajtu w jego szesnastkowym wyglądzie. Na przykład wiemy, że wartość dziesiętna 255ma 0xFFwygląd szesnastkowy:
val ='{:02x}'.format(255)
sys.stdout.write(val)# prints ff2print(val)# prints ff
Nie o to chodzi. Działo się tak tylko w interaktywnej powłoce, ponieważ ... write()nie dodawała \ni nie zwraca (i interaktywne wyświetlanie powłoki) wartości zwracanej przez funkcję (liczba zapisanych znaków), reprezentacji szesnastkowej lub jakiejkolwiek innej wyświetlanej treści jest nieistotna.
Ondrej K.
0
W Pythonie 2, jeśli chcesz przekazać funkcję, możesz przypisać os.sys.stdout.write do zmiennej, nie możesz tego zrobić (w replice) za pomocą print.
>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>>
To działa zgodnie z oczekiwaniami.
>>> cmd=printFile"<stdin>", line 1
cmd=print^SyntaxError: invalid syntax
Różnica między printi, sys.stdout.writeaby wskazać w Pythonie 3, to także wartość zwracana po wykonaniu w terminalu. W Pythonie 3 sys.stdout.writezwraca długość ciągu, podczas gdy printzwraca tylkoNone .
Na przykład uruchomienie interaktywnego kodu w terminalu wypisuje ciąg znaków wraz z jego długością, ponieważ długość jest zwracana i wyprowadzana po uruchomieniu interaktywnym:
sys.stdout.write()
iprint
(i / lub dlaczego Python ma oba) jest całkowicie rozsądnym pytaniem i nie wymaga przykładów. OP nie powiedział, że składnia polecenia jest myląca.Odpowiedzi:
print
jest tylko cienkim opakowaniem, które formatuje dane wejściowe (modyfikowalne, ale domyślnie ze spacją między argumentami i znakiem nowej linii na końcu) i wywołuje funkcję zapisu danego obiektu. Domyślnie ten obiekt jestsys.stdout
, ale plik można przekazać za pomocą formularza „chevron”. Na przykład:Zobacz: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement
W Pythonie 3.x
print
staje się funkcją, ale nadal można przekazać coś innego niżsys.stdout
dziękifile
argumentowi.Zobacz https://docs.python.org/3/library/functions.html#print
W Pythonie 2.6+
print
wciąż jest instrukcją, ale może być używana jako funkcja zAktualizacja: Bakuriu skomentował, że istnieje niewielka różnica między funkcją print a instrukcją print (a bardziej ogólnie między funkcją a instrukcją).
W przypadku błędu podczas oceny argumentów:
źródło
print
dodaje także nowy wiersz do wszystkiego, co piszesz, co się nie zdarzasys.stdout.write
.sys.stdout.write
Jest także bardziej uniwersalny, jeśli kiedykolwiek będziesz musiał napisać kod podwójnej wersji (np. Kod, który działa jednocześnie z Python 2.x oraz Python 3.x).print
print "this",; print "on the same line as this"
>>
jest tutaj operatorem rshift, ale specyficzną formą „chevron”print
instrukcji. Zobacz docs.python.org/2/reference/…sys.stdout.write()
buforuje również dane wejściowe i może nie natychmiast opróżnić dane wejściowe do fd. aby upewnić się, że zachowuje się jak funkcja drukowania, należy dodać:sys.stdout.flush()
print
Najpierw konwertuje obiekt na ciąg (jeśli nie jest to już ciąg). Umieści także spację przed obiektem, jeśli nie jest to początek linii i znak nowej linii na końcu.Podczas używania
stdout
musisz samodzielnie przekonwertować obiekt na ciąg znaków (na przykład przez wywołanie „str”) i nie ma znaku nowej linii.Więc
jest równa:
źródło
print
i.write()
, powiedziałbym.print
można wprowadzić pominięcie nowej linii. W Pythonie 2.x umieść przecinek na końcu, a spacja zostanie wypisana, ale nie będzie nowego wiersza. Np.print 99,
W Pythonie 3,print(..., end='')
unikniesz dodawania nowej linii (a także unikniesz dodawania spacji, chyba że to zrobiszend=' '
.print
działanie zachowuje się nieco inaczej w procedurach obsługi sygnałów w python2.X, tzn. print nie może być zastąpiony przez sys.stdout w przykładzie: stackoverflow.com/questions/10777610/…Po zakończeniu opracowywania skryptu innego dnia przesłałem go na serwer unix. Wszystkie moje komunikaty debugowania używały
print
instrukcji, które nie pojawiają się w dzienniku serwera.Jest to przypadek, w którym możesz potrzebować
sys.stdout.write
zamiast tego.źródło
print()
isys.stdout.write()
, w przeciwieństwie do różnicy międzystdout
istderr
? Do debugowania należy użyćlogging
modułu, na którym drukowane są wiadomościstderr
.nohup
i przekierowywania do.out
pliku.nohup
, domyślnie całe pisanie dostdout
istderr
zostanie przekierowanenohup.out
, niezależnie od tego, czy używasz,print
czystdout.write
.Oto przykładowy kod oparty na książce Learning Python autorstwa Mark Lutz, który odpowiada na twoje pytanie:
Otwarcie log.txt w edytorze tekstu ujawni następujące informacje:
źródło
Jest co najmniej jedna sytuacja, w której chcesz
sys.stdout
zamiast drukować.Jeśli chcesz zastąpić linię bez przechodzenia do następnej linii, na przykład podczas rysowania paska postępu lub komunikatu o stanie , musisz zapętlić coś takiego jak
A ponieważ print dodaje nowy wiersz, lepiej jest używać
sys.stdout
.źródło
Jeśli piszesz aplikację wiersza polecenia, która może zapisywać zarówno pliki, jak i standardowe wyjście, jest to przydatne. Możesz robić takie rzeczy jak:
Oznacza to, że nie możesz użyć tego
with open(outfile, 'w') as out:
wzoru, ale czasem warto.źródło
with
-def process(output): # ...
/if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)
(dodawanie nowych linii w razie potrzeby oczywiście). To na pewno niezbyt czyste, to na pewno.W wersji 2.x
print
instrukcja przetwarza to, co dajesz, przekształcając ją w ciągi po drodze, obsługując separatory i znaki nowej linii oraz umożliwiając przekierowanie do pliku. 3.x zamienia go w funkcję, ale nadal ma te same obowiązki.sys.stdout
jest plikiem lub podobnym do pliku, który ma metody zapisu do niego, które pobierają ciągi lub coś wzdłuż tej linii.źródło
wskazane jest, gdy przydatne jest drukowanie dynamiczne, na przykład w celu dostarczenia informacji w długim procesie:
źródło
Obserwując powyższy przykład:
sys.stdout.write
nie napisze obiektu nie łańcuchowego, aleprint
będziesys.stdout.write
nie doda nowego symbolu linii na końcu, aleprint
zrobi toJeśli zanurzymy się głęboko,
sys.stdout
to obiekt pliku, którego można użyć do wydruku print ()jeśli
print()
nie określono argumentu pliku ,sys.stdout
zostanie użytyźródło
Na przykład pracuję nad małą funkcją, która drukuje gwiazdy w formacie piramidy po przekazaniu liczby jako argumentu, chociaż możesz to zrobić za pomocą end = "", aby wydrukować w osobnej linii, użyłem sys.stdout.write w koordynacji z nadrukiem, aby to zadziałało. Aby rozwinąć tę kwestię, stdout.write drukuje w tej samej linii, gdzie jako print zawsze drukuje jej zawartość w osobnej linii.
źródło
Przekonałem się, że standardowe wyjście działa lepiej niż drukowanie w sytuacji wielowątkowości. Używam kolejki (FIFO) do przechowywania linii do wydrukowania i trzymam wszystkie wątki przed linią drukowania, aż mój wydruk Q będzie pusty. Mimo to, używając print, czasami tracę końcowy \ n debugowania I / O (używając wing pro IDE).
Kiedy używam std.out z \ n w ciągu, debugowane we / wy formatuje poprawnie, a \ n są dokładnie wyświetlane.
źródło
W Pythonie 3 istnieje prawidłowy powód, dla którego warto zastosować print
sys.stdout.write
, ale ten powód można również zmienić w powód do użyciasys.stdout.write
zamiast tego.Powodem jest to, że teraz print jest funkcją w Pythonie 3, możesz to zmienić. Możesz więc używać print wszędzie w prostym skrypcie i zdecydować, że te instrukcje drukowania muszą pisać w
stderr
zamian. Teraz możesz po prostu przedefiniować funkcję drukowania, możesz nawet zmienić funkcję drukowania globalną, zmieniając ją za pomocą wbudowanego modułu. Oczywiście, że zfile.write
możesz określić, co to jest plik, ale w przypadku nadpisywania wydruku możesz również przedefiniować separator linii lub separator argumentów.Odwrotnie jest. Być może jesteś absolutnie pewien, że piszesz
stdout
, ale wiesz również, że zamierzasz zmienić druk na coś innego, z czego możesz zdecydować się skorzystaćsys.stdout.write
i użyj print do dziennika błędów lub czegoś innego.To, czego używasz, zależy od tego, jak zamierzasz go używać.
print
jest bardziej elastyczny, ale może to być powód do korzystania i nieużywania go. Nadal wybrałbym elastyczność i wybrałbym druk. Innym powodem użyciaprint
zamiast tego jest znajomość. Więcej osób zrozumie teraz, co masz na myśli przez druk, a mniej wiesys.stdout.write
.źródło
Jedną z różnic jest to, że podczas próby wydrukowania bajtu w jego szesnastkowym wyglądzie. Na przykład wiemy, że wartość dziesiętna
255
ma0xFF
wygląd szesnastkowy:źródło
write()
nie dodawała\n
i nie zwraca (i interaktywne wyświetlanie powłoki) wartości zwracanej przez funkcję (liczba zapisanych znaków), reprezentacji szesnastkowej lub jakiejkolwiek innej wyświetlanej treści jest nieistotna.W Pythonie 2, jeśli chcesz przekazać funkcję, możesz przypisać os.sys.stdout.write do zmiennej, nie możesz tego zrobić (w replice) za pomocą print.
To działa zgodnie z oczekiwaniami.
To nie działa. druk jest magiczną funkcją.
źródło
Różnica między
print
i,sys.stdout.write
aby wskazać w Pythonie 3, to także wartość zwracana po wykonaniu w terminalu. W Pythonie 3sys.stdout.write
zwraca długość ciągu, podczas gdyprint
zwraca tylkoNone
.Na przykład uruchomienie interaktywnego kodu w terminalu wypisuje ciąg znaków wraz z jego długością, ponieważ długość jest zwracana i wyprowadzana po uruchomieniu interaktywnym:
źródło