Sys.stdout.write ve print arasındaki fark?


376

sys.stdout.write()Tercih edilebilecek durumlar var printmı?

( Örnekler: daha iyi performans; daha anlamlı kod)


4
Hangi Python sürümü? 2.x veya 3.x?
Mark Byers

Dürüst olmak gerekirse, Python 3 ile hiçbir deneyimim olmasa da, her ikisini de bilmek istiyorum.
Johanna Larsson

17
@ S.Lott: sys.stdout.write()ve print(ve / veya Python'un neden her ikisine birden sahip olduğu) arasındaki temel farklılıkları sormak son derece makul bir sorudur ve örneklere ihtiyaç duymaz. OP komut sözdiziminin kafa karıştırıcı olduğunu söylemedi.
smci

Yanıtlar:


294

printyalnızca girişleri biçimlendiren (değiştirilebilir, ancak varsayılan olarak argümanlar ve sonunda satırsonu arasında bir boşluk bulunan) ve belirli bir nesnenin yazma işlevini çağıran ince bir sargıdır. Bu nesne varsayılan sys.stdoutolarak "chevron" formunu kullanarak bir dosya iletebilirsiniz. Örneğin:

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

Bkz. Https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


Python 3.x'te printbir işlev haline gelir, ancak argüman sys.stdoutsayesinde başka bir şey iletmek yine de mümkündür file.

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

Bkz. Https://docs.python.org/3/library/functions.html#print


Python 2.6+ sürümünde, printhala bir deyimdir, ancak şu işlevlerle kullanılabilir:

from __future__ import print_function

Güncelleme: Bakuriu, print işlevi ile print ifadesi arasında (ve daha genel olarak bir işlev ile bir deyim arasında) küçük bir fark olduğunu belirtti.

Argümanları değerlendirirken bir hata olması durumunda:

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The function is not called

64
Ayrıca, printyazdığınız her şeye de bir satırsonu ekleyen ve bu gerçekleşmeyen şeyleri belirtmek gerekir sys.stdout.write.
Michael Mior

5
Ayrıca sys.stdout.write, çift sürüm kodu yazmanız gerektiğinde daha evrenseldir (örneğin, Python 2.x ve Python 3.x ile aynı anda çalışan kod).
andreb

3
@MichaelMior printSondaki virgülle print "this",; print "on the same line as this"
eklenen

1
@ bjd2385 >>Burada rshift operatörü değil, ifadenin belirli bir "chevron" formu print. Bkz. Docs.python.org/2/reference/…
luc

5
sys.stdout.write()ayrıca girişi arabelleğe alır ve girişi hemen fd'ye basmayabilir. Yazdırma işlevi gibi davrandığından emin olmak için şunları eklemelisiniz: sys.stdout.flush()
kerbelp

151

printönce nesneyi bir dizeye dönüştürür (zaten bir dize değilse). Ayrıca, bir satırın başlangıcı ve sonunda bir yeni satır karakteri değilse nesnenin önüne bir boşluk koyacaktır.

Kullanırken stdout , nesneyi kendiniz bir dizeye dönüştürmeniz gerekir (örneğin "str" ​​çağrısı yaparak) ve yeni satır karakteri yoktur.

Yani

print 99

şuna eşittir:

import sys
sys.stdout.write(str(99) + '\n')

32
Yeni satır karakterinden bahsettiğiniz için +1! Bu arasındaki temel farktır printve .write()diyebilirim.
Eric O Lebigot

9
NOT: printyeni satırı atlamak için yapılabilir. Python 2.x'de, sonuna virgül koyun, boşluk karakteri çıkacak, ancak satırsonu çıkmayacak. Örneğin print 99,In Python 3, print(..., end='')yapmanız sürece yeni satır eklemekten kaçının (ve aynı zamanda, uzay eklemekten kaçının end=' '.
ToolmakerSteve

40
@EOL Bu ne komik, EOL adında biri '\ n' hakkında yorum yapıyor ... Beni güldürdü. Hayatim YOK. Beni öldür.
Depado

2
bu doğru DEĞİLDİR, printişlem
python2.X'deki

41

Sorum sys.stdout.write(), tercih edilebilecek durumlar olup olmadığıdır . print

Geçen gün bir senaryo geliştirmeyi bitirdikten sonra, bir unix sunucusuna yükledim. Bütün ayıklama mesajları kullanılan printifadeler ve bunlar yok bir sunucu günlüğüne görünür.

Bu, sys.stdout.writebunun yerine ihtiyaç duyabileceğiniz bir durumdur .


8
ha? Bu arasında bir fark olduğuna emin misin print()ve sys.stdout.write()arasındaki fark aksine, stdoutve stderr? Hata ayıklama için, loggingiletileri yazdıran modülü kullanmanız gerekir stderr.
ostrokach

1
Ya. Aynı şey nohupbir .outdosyayı kullanmak ve yeniden yönlendirmek için de geçerlidir .
conner.xyz

1
sys.stdout.flush () kullanımı yardımcı olacaktır.
suprit chaudhary

Eğer kullanırsanız nohup, varsayılan olarak, tüm yazı stdoutve stderryeniden yönlendirilmiş olacak nohup.outkullanmak ister göz ardı ederek printveya stdout.write.
Zheng Liu

40

İşte Mark Lutz'un Learning Python adlı kitabına dayanan ve sorunuza cevap veren bazı örnek kodlar :

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive prompt
print("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 prompt
print("back to normal")           # this shows up in the interactive prompt

Log.txt dosyasını bir metin düzenleyicide açmak aşağıdakileri ortaya çıkarır:

testing123
another line

Dosyaya yazmanın yanı sıra ekrana yazdırabileceğim bir yol var mı?
Devesh Saini

5
@DeveshSaini: Evet, sys.stdout dosyasının üzerine en azından write () ve flush () işlevine sahip bir proxy sınıfı yaz. Ben bir örnek pasajı yazmış buraya .
ponycat

14

sys.stdoutYazdırmak yerine istediğiniz en az bir durum vardır .

Bir sonraki satıra gitmeden bir satırın üzerine yazmak istediğinizde, örneğin bir ilerleme çubuğu veya durum mesajı çizerken ,

Note carriage return-> "\rMy Status Message: %s" % progress

Ve baskı bir satırsonu eklediğinden, kullanmanız daha iyi olur sys.stdout.


2
Eğer baskı yeni bir satır eklerse, neden sadece baskı ('mesaj', end = '') yapmıyorsunuz?
Apoorv Patne

8

Sorum sys.stdout.write(), tercih edilebilecek durumlar olup olmadığıdır .print

Hem dosyalara hem de stdout'a yazabilen bir komut satırı uygulaması yazıyorsanız, kullanışlı olur. Şöyle şeyler yapabilirsiniz:

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

Bu, with open(outfile, 'w') as out:deseni kullanamayacağınız anlamına gelir , ancak bazen buna değer.


Kesin, konuşarak yapabilirsiniz kullanmak with- def process(output): # .../ if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)(burada elbette gerekli yeni satırlar ekleyerek). Kesinlikle çok temiz değil, ama, kesin.
Monica'nın Davası

4

2.x'de ifade, printverdiklerinizi önceden işler, yol boyunca dizelere dönüştürür, ayırıcıları ve satırsonlarını işler ve bir dosyaya yeniden yönlendirmeye izin verir. 3.x onu bir işleve dönüştürür, ancak yine de aynı sorumluluklara sahiptir.

sys.stdout , bu satır boyunca dizeler veya başka bir şey alan yazma yöntemleri içeren bir dosya veya dosya benzeri bir dosyadır.


3

dinamik baskı, örneğin uzun bir süreçte bilgi vermek için yararlı olduğunda tercih edilir:

import time, sys
Iterations = 555
for 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)

2
print (time_msg, end = '') yerine sys.stdout.write (time_msg) sys.stdout.flush () da çalışır
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

Yukarıdaki örneği inceleyerek:

  1. sys.stdout.writeolmayan dize nesnesini yazmak olmaz, ama printolacak

  2. sys.stdout.writeSonunda yeni bir satır sembolü eklemek ama olmaz printwill

Derinlere dalarsak,

sys.stdout print () çıktısı için kullanılabilen bir dosya nesnesidir

dosya argümanı print()belirtilmezse sys.stdoutkullanılır


1

Yazdırmak için sys.stdout.write () yönteminin tercih edildiği durumlar var mı?

Örneğin, sayıyı bağımsız değişken olarak ilettikten sonra yıldızları piramit biçiminde basan küçük işlev üzerinde çalışıyorum, ancak bunu ayrı bir satırda yazdırmak için end = "" kullanarak yapabilirsiniz , koordinasyonda sys.stdout.write kullandım ile baskı bu işi yapmak için. Bu konuda ayrıntılı için stdout.write aynı çizgide baskılar baskı her zaman ayrı bir satırda içeriğini yazdırır.

import sys

def printstars(count):

    if count >= 1:
        i = 1
        while (i <= count):
            x=0
            while(x<i):
                sys.stdout.write('*')
                x = x+1
            print('')
            i=i+1

printstars(5)

1

Yazdırmak için sys.stdout.write () yönteminin tercih edildiği durumlar var mı?

Stdout'un çok iş parçacıklı bir durumda yazdırmaktan daha iyi çalıştığını buldum. Yazdırılacak satırları saklamak için Kuyruk (FIFO) kullanıyorum ve baskı Q'um boşalana kadar tüm konuları baskı hattından önce tutuyorum. Yine de, print kullanarak bazen hata ayıklama G / Ç'sindeki final \ n değerini kaybederim (wing pro IDE kullanarak).

Dizede \ n ile std.out kullandığımda hata ayıklama G / Ç biçimleri doğru şekilde biçimlendirilir ve \ n değerleri doğru olarak görüntülenir.


Bu durumda stdout'un yazdırmadan daha iyi çalışması için herhangi bir neden biliyor musunuz, yoksa bu anekdot mu? Bunun olduğu yerde minimal bir çalışma örneği verebilir misiniz?
user2653663

Benim düşüncem, stdout'un baskıdan daha düşük bir seviyede çalıştığıdır. İki baskı rutini stdout ile beslenmek için savaşırken kesinlikle iplik bozulması vardı. Her iş parçacığından bir stdout yazmak benim için yolsuzluk kaldırıldı.
David Poundall


1

Python 3'te baskıyı kullanmak için geçerli bir neden vardır sys.stdout.write, ancak bu neden sys.stdout.writebunun yerine kullanım nedenine dönüştürülebilir .

Bu nedenle, şimdi yazdırma Python 3'te bir işlevdir, bunu geçersiz kılabilirsiniz. Böylece print'i her yerde basit bir komut dosyasında kullanabilir ve bu baskı ifadelerininstderr bunun yerine . Artık yazdırma işlevini yeniden tanımlayabilirsiniz, hatta yerleşik modülleri kullanarak yazdırma işlevini global olarak değiştirebilirsiniz. Tabii ki, file.writehangi dosyanın olduğunu belirtebilirsiniz, ancak üzerine yazma baskısı ile satır ayırıcıyı veya bağımsız değişken ayırıcıyı da yeniden tanımlayabilirsiniz.

Diğer yol ise. Belki de yazacağından kesinlikle eminsinstdout , ancak baskıyı başka bir şeye değiştireceğinizi de bilirsiniz sys.stdout.write, hata günlüğü veya başka bir şey için baskıyı kullanmaya karar verebilirsiniz .

Yani, kullandığınız şey onu nasıl kullanmayı planladığınıza bağlıdır. printdaha esnektir, ancak bu kullanımı ve kullanılmaması için bir neden olabilir. Yine de esnekliği tercih eder ve yazdırmayı seçerdim. printBunun yerine kullanmanın bir başka nedeni de aşinalıktır. Artık daha çok insan ne demek istediğinizi basılı ve daha az biliyor sys.stdout.write.


1

Bir baytın onaltılık görünümüne yazdırılmaya çalışılırken farktan biri aşağıdadır. Örneğin, söz konusu ondalık değerini bilmek 255olduğunu 0xFFonaltılık görünüm:

val = '{:02x}'.format(255) 

sys.stdout.write(val) # prints ff2
print(val)            # prints ff

Bunun konusu bu değil. Bu yalnızca etkileşimli bir kabukta gerçekleşir ve ... işlevinin dönüş değerini (ve etkileşimli kabuk ekranlarını) write()eklemediğinden \nve döndürmediğinden (yazılan karakter sayısı), onaltılı gösterim veya görüntülenen diğer herhangi bir içerik önemsizdir.
Ondrej K.

0

Python 2'de bir fonksiyonun etrafından geçmeniz gerekiyorsa, os.sys.stdout.write öğesini bir değişkene atayabilirsiniz, bunu print ile (yapamazsınız) yapamazsınız.

>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>> 

Beklendiği gibi çalışıyor.

>>> cmd=print
  File "<stdin>", line 1
    cmd=print
            ^
SyntaxError: invalid syntax

Bu çalışmıyor. baskı büyülü bir işlevdir.


0

Python 3'te printve sys.stdout.writeişaret etmek arasındaki fark , terminalde yürütüldüğünde döndürülen değerdir. Python 3 sys.stdout.writeoysa dize boyunu döndürür printdöndürür sadeceNone .

Örneğin, terminalde etkileşimli olarak aşağıdaki kodu çalıştırmak, dizeyi ve ardından uzunluğunu yazdırır, çünkü uzunluk etkileşimli olarak çalıştırıldığında döndürülür ve çıkarılır:

>>> sys.stdout.write(" hi ")
 hi 4
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.