2010-05-23 17 views
7

benim ekran mesajları renklendirmek için aşağıdaki işlevleri vardır: şöyle ben bunları kullanmakSTDOUT Basım ve ANSI renk kodlarını kaldırılırken log dosyası

def error(string): 
    return '\033[31;1m' + string + '\033[0m' 

def standout(string): 
    return '\033[34;1m' + string + '\033[0m' 

:

print error('There was a problem with the program') 
print "This is normal " + standout("and this stands out") 

Ben log istiyorum umarım her print açıklamaya ikinci "günlük" satırını eklemek zorunda kalmadan ANSI renk kodları oLMADAN (STDOUT ek olarak) bir dosyaya çıktı.

Bunun nedeni, python program.py > out ise, out dosyasının, düz bir metin düzenleyicide açtığınızda korkunç görünen ANSI renk kodlarına sahip olmasıdır.

Herhangi bir öneri?

cevap

9

sys.stdout.isatty fonksiyonu yardımcı olabilir:

varsayılan argümanlar derleme sırasında değerlendirilir çünkü aslında None olarak ayarlanmamış varsayılan bir değişkeni kullanmaya Aklıma gelen birkaç kullanımla biri
from sys import stdout 

def error(string, is_tty=stdout.isatty()): 
    return ('\033[31;1m' + string + '\033[0m') if is_tty else string 

def standout(string, is_tty=stdout.isatty()): 
    return ('\033[34;1m' + string + '\033[0m') if is_tty else string 

Python'da zaman, C++ gibi bir çalışma süresinden daha fazla ...

Gerçekten gerek duyuyorsanız, davranış açıkça yönlendirilebilir; ancak bu, yeniden yönlendirildiğinde kodlamayı kendinizin yapmasına izin vermez. Eğer logging modülünü (belki bu konuda bilmiyordum) kullanmadığınız bir nedeni var mı? Eğer terminal ve bir günlük dosyasına hem baskı almak isteyen olursa

+0

Mükemmel cevap biçimlendirme zorlamak için küçük bir değişiklik ihtiyacı var - bu tam olarak ne ihtiyacım olabilir. Aslında günlük modülü kullanarak, ancak kullanıcı çıkışını yönlendirmek ve bir insan okunabilir dosya almak seçeneğine sahip izin vermek istiyorum duyuyorum. Günlüğün kendisi, günlüğe kaydetme modülü tarafından oluşturulur (ve yaklaşımınızla büyük ihtimalle istediğimi alırım). – Escualo

+0

Sadece yaklaşımınızı test ettim ve tam olarak beklendiği gibi çalışıyor. Çok teşekkürler! – Escualo

5

, o zaman günlük modülü kullanarak öneririm. Hatta özel bir biçimlendirici tanımlayabilirsiniz, bu nedenle dosyaya giriş terminali kodlarını temizlemek edebilirsiniz:

import optparse 
import logging 

def error(string): 
    return '\033[31;1m' + string + '\033[0m' 

def standout(string): 
    return '\033[34;1m' + string + '\033[0m' 

def plain(string): 
    return string.replace('\033[34;1m','').replace('\033[31;1m','').replace('\033[0m','') 

if __name__=='__main__': 
    logging.basicConfig(level=logging.DEBUG, 
         format='%(message)s', 
         filemode='w') 
    logger=logging.getLogger(__name__)  
    def parse_options():  
     usage = 'usage: %prog [Options]' 
     parser = optparse.OptionParser() 
     parser.add_option('-l', '--logfile', dest='logfile', 
          help='use log file') 
     opt,args = parser.parse_args() 
     return opt,args 
    opt,args=parse_options() 
    if opt.logfile: 
     class MyFormatter(logging.Formatter): 
      def format(self,record): 
       return plain(record.msg) 
     fh = logging.FileHandler(opt.logfile) 
     fh.setLevel(logging.INFO) 
     formatter = MyFormatter('%(message)s') 
     fh.setFormatter(formatter) 
     logging.getLogger('').addHandler(fh) 

    logger.info(error('There was a problem with the program')) 
    logger.info("This is normal " + standout("and this stands out")) 

test.py baskılar sadece terminale.

test.py -l test.out baskı, her iki terminal ve dosya test.out için. günlük hiçbiri sahipken Her durumda

, terminale metin, renk kodları vardır.

1

unubtu cevabı aşağıda harika ama MyFormatter biçimi() yönteminde

class MyFormatter(logging.Formatter): 
     def format(self,record): 
      msg = super(MyFormatter, self).format(record) 
      return plain(msg) 
İlgili konular