Prima di tutto, self.stdout
è un'istanza del comando django.core.management.base.OutputWrapper
. La sua write
aspetta un str
, non bytes
, in tal modo è possibile utilizzare
self.stdout.write('hello ', ending='')
self.stdout.write('world')
realtà self.stdout.write
non accetta byte, ma solo quando il ending
è una stringa vuota - che è perché il suo metodo write
è definito
def write(self, msg, style_func=None, ending=None):
ending = self.ending if ending is None else ending
if ending and not msg.endswith(ending):
msg += ending
style_func = style_func or self.style_func
self._out.write(force_str(style_func(msg)))
Se ending
è vero, allora msg.endswith(ending)
avrà esito negativo se msg
è un'istanza bytes
e un finale è un str
.
Inoltre, print
con self.stdout
funziona correttamente quando imposto lo self.stdout.ending = ''
in modo esplicito; tuttavia, ciò potrebbe significare che un altro codice che utilizza self.stdout.write
in attesa di inserimento di nuove righe non riuscirebbe.
Nel tuo caso, cosa farei è quello di definire un metodo per la print
Command
:
from django.core.management.base import OutputWrapper
class PrintHelper:
def __init__(self, wrapped):
self.wrapped = wrapped
def write(self, s):
if isinstance(self.wrapped, OutputWrapper):
self.wrapped.write(s, ending='')
else:
self.wrapped.write(s)
class Command(BaseCommand):
def print(self, *args, file=None, **kwargs):
if file is None:
file = self.stdout
print(*args, file=PrintHelper(file), **kwargs)
def handle(self, *args, **options):
self.print('hello ', end='')
self.print('world')
È possibile effettuare questo nel proprio BaseCommand
sottoclasse - e lo si può utilizzare con diversi i file troppo:
def handle(self, *args, **options):
for c in '|/-\\' * 100:
self.print('\rhello world: ' + c, end='', file=self.stderr)
time.sleep(0.1)
self.print('\bOK')
Il tuo caso d'uso è più lungo delle linee di creazione di un'intera stringa di testo basata su elementi concomitanti ecc. La ragione per cui lo chiedo è, se l'intera stringa è conosciuta in anticipo, come nel caso di "Ciao mondo" tu potrebbe essere facilmente scritto come una linea completa mentre si utilizza la stampa senza stdout.write per avvalersi del controllo sul carattere finale di fine riga. Pertanto, supponendo che non si conosca il testo in anticipo, non è possibile creare il testo aggiungendo le stringhe finché il testo completo non è pronto per la stampa. –
correlati: http://stackoverflow.com/questions/31926422/redirection-in-django-command-called-from-another-command-results-in-est-aneous. E se non trovi una soluzione, ti consiglio di scrivere un decoratore o un gestore di contesto che rattoppi temporaneamente 'print' e/o' self.stdout' per comportarsi nel modo desiderato. –
Non capisco come usare 'self.stdout.ending = ''" "impedisce a [tu] di usare la funzione di stampa e tutte le sue belle funzionalità". Puoi ancora usare 'print', e l'output sarà quello che ti aspetti, qual è il problema? – Louis