LINUX.ORG.RU

История изменений

Исправление user_id_68054, (текущая версия) :

вообще хорошего *универсального* решения тут не думаю что можно придумать :)).

так как — вдруг stdout должен быть в другой кодеровке (не UTF-8) ? и должны ли мы хардкодно указывать UTF-8 или же должны ли мы взять значение из локали? это зависит от задачи..

но в целом — как костыль — это норм.

и можно этот костыль даже слегка улучшить:

import sys
import codecs
if not getattr(sys.stdout, 'encoding', None):
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)

ну или сделать примерно-где-то-вот-так

import sys

def safe_print(*args, **kwargs):
    sep=kwargs.get('sep', u' ')
    end=kwargs.get('end', u'\n')
    file=kwargs.get('file', sys.stdout)
    
    def safe_conv(value):
        encoding = getattr(file, 'encoding', None) or 'utf-8'
        
        if isinstance(value, bytes):
            safe_value = value
        elif isinstance(value, unicode):
            safe_value = value.encode(encoding, 'replace')
        else:
            safe_value = unicode(value).encode(encoding, 'replace')
        
        return safe_value
    
    print_str = safe_conv(sep).join(safe_conv(v) for v in args) + safe_conv(end)
    
    file.write(print_str)
    file.flush()

Исправление user_id_68054, :

вообще хорошего *универсального* решения тут не думаю что можно придумать :)).

так как — вдруг stdout должен быть в другой кодеровке (не UTF-8) ? и должны ли мы хардкодно указывать UTF-8 или же должны ли мы взять значение из локали? это зависит от задачи..

но в целом — как костыль — это норм.

и можно этот костыль даже слегка улучшить:

import sys
import codecs
if not getattr(sys.stdout, 'encoding', None):
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)

ну или сделать примерно-где-то-вот-так

import sys

def safe_print(*args, **kwargs):
    sep=kwargs.get('sep')
    end=kwargs.get('end')
    file=kwargs.get('file')
    
    if sep is None:
        sep = u' '
    if end is None:
        end = u'\n'
    if file is None:
        file = sys.stdout
    
    def safe_conv(value):
        encoding = getattr(file, 'encoding', None) or 'utf-8'
        
        if isinstance(value, bytes):
            safe_value = value
        elif isinstance(value, unicode):
            safe_value = value.encode(encoding, 'replace')
        else:
            safe_value = unicode(value).encode(encoding, 'replace')
        
        return safe_value
    
    print_str = safe_conv(sep).join(safe_conv(v) for v in args) + safe_conv(end)
    
    file.write(print_str)
    file.flush()

Исходная версия user_id_68054, :

вообще хорошего *универсального* решения тут не думаю что можно придумать :)).

так как — вдруг stdout должен быть в другой кодеровке (не UTF-8) ? и должны ли мы хардкодно указывать UTF-8 или же должны ли мы взять значение из локали? это зависит от задачи..

но в целом — как костыль — это норм.

и можно этот костыль даже слегка улучшить:

import sys
import codecs
if not getattr(sys.stdout, 'encoding', None):
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)

ну или сделать примерно-где-то-вот-так

import sys

def safe_print(*args, **kwargs):
    sep=kwargs.get('sep')
    end=kwargs.get('end')
    file=kwargs.get('file')
    
    if sep is None:
        sep = ' '
    if end is None:
        end = '\n'
    if file is None:
        file = sys.stdout
    
    def safe_conv(value):
        encoding = getattr(file, 'encoding', None) or 'utf-8'
        
        if isinstance(value, bytes):
            safe_value = value
        elif isinstance(value, unicode):
            safe_value = value.encode(encoding, 'replace')
        else:
            safe_value = unicode(value).encode(encoding, 'replace')
        
        return safe_value
    
    print_str = safe_conv(sep).join(safe_conv(v) for v in args) + safe_conv(end)
    
    file.write(print_str)
    file.flush()