Scopri tutte le cose che puoi fare con Python textwrap
modulo, inclusa formattazione, disposizione del testo, ritaglio e altro
Python ha molte opzioni per formattare stringhe e testo, incluse f-string, format()
funzione, modelli e altro ancora. C’è però un modulo che pochi conoscono e si chiama textwrap
.
Questo modulo è stato creato appositamente per aiutarti con il ritorno a capo, il rientro, il taglio e altro ancora, e in questo articolo esamineremo tutte le cose per cui puoi usarlo.
Cominciamo con una funzione molto semplice ma molto utile del file textwrap
modulo, chiamato shorten
:
from textwrap import shortenshorten("This is a long text or sentence.", width=10)
# 'This (...)'
shorten("This is a long text or sentence.", width=15)
# 'This is a (...)'
shorten("This is a long text or sentence.", width=15, placeholder=" <...>")
# 'This is a <...>'
Come suggerisce il nome, shorten
ci permette di tagliare il testo ad una certa lunghezza ( width
) se la stringa specificata è troppo lunga. Per impostazione predefinita, il segnaposto per il testo ritagliato è (...)
ma questo può essere sovrascritto con il placeholder
discussione.
Una funzione più interessante di questo modulo è wrap
. Il caso d’uso ovvio è dividere il testo lungo in righe della stessa lunghezza, ma ci sono altre cose che possiamo fare con esso:
from textwrap import wrap
s = '1234567890'
wrap(s, 3)
# ('123', '456', '789', '0')
In questo esempio dividiamo una stringa in parti uguali che possono essere utili per l’elaborazione batch, piuttosto che solo per la formattazione.
L’utilizzo di questa funzione, tuttavia, presenta alcuni avvertimenti:
s = '12\n3 45678\t9\n0'
wrap(s, 3)
# ('12', '3 ', '456', '78', '9 0')
# the first ("12") element "includes" newline
# the 4th element ("78") "includes" tab
wrap(s, 3, drop_whitespace=False, tabsize=1)
# ('12 ', '3 ', '456', '78 ', '9 0')
Dovresti fare attenzione agli spazi bianchi durante l’utilizzo wrap
– sopra puoi vedere il comportamento con i caratteri di nuova riga, tabulazione e spazio. Puoi vedere che il primo elemento ( 12
) “include” nuova riga e 4° elemento ( 78
) “include” scheda, questi vengono tuttavia eliminati per impostazione predefinita, quindi questi elementi hanno solo 2 caratteri invece di 3.
Possiamo specificare il drop_whitespace
argomento con parola chiave per preservarli e mantenere la lunghezza corretta dei blocchi.
Potrebbe essere ovvio, ma wrap
è ottimo anche per riformattare interi file con una determinata larghezza di linea:
with open("some-text.md", "r", encoding="utf-8") as f:
formatted = wrap(f.read(), width=80) # List of lines
formatted = fill(f.read(), width=80) # Single string that includes line breaks
# ... write it back
Possiamo anche usare il fill
funzione che è una scorciatoia per "\n".join(wrap(text, ...))
. La differenza tra i 2 è questa wrap
ci fornirà un elenco di righe di cui avremo bisogno per concatenarci, e fill
ci dà una singola stringa che è già stata unita utilizzando i ritorni a capo.
textwrap
il modulo include anche una versione più potente wrap
funzione, che è a TextWrapper
classe:
import textwrapw = textwrap.TextWrapper(width=120, placeholder=" <...>")
for s in list_of_strings:
w.wrap(s)
# ...
Questa classe e la sua wrap
il metodo è ottimo se dobbiamo chiamare wrap
con gli stessi parametri più volte come mostrato sopra.
E mentre stiamo cercando che il TextWrapper
proviamo anche altri argomenti relativi alle parole chiave:
user = "John"
prefix = user + ": "
width = 50
wrapper = TextWrapper(initial_indent=prefix, width=width, subsequent_indent=" " * len(prefix))
messages = ("...", "...", "...")
for m in messages:
print(wrapper.fill(m))# John: Lorem Ipsum is simply dummy text of the
# printing and typesetting industry. Lorem
# John: Ipsum has been the industry's standard dummy
# text ever since the 1500s, when an
# John: unknown printer took a galley of type and
# scrambled it to make a type specimen
Qui possiamo vedere l’uso di initial_indent
E subsequent_indent
per rientrare rispettivamente la prima riga del paragrafo e quelle successive. Ci sono un paio di altre opzioni che puoi trovare in documenti.
Inoltre, perché TextWrapper
è una classe, possiamo anche estenderla e sovrascrivere completamente alcuni dei suoi metodi:
from textwrap import TextWrapperclass DocumentWrapper(TextWrapper):
def wrap(self, text):
split_text = text.split('\n')
lines = (line for par in split_text for line in TextWrapper.wrap(self, par))
return lines
text = """First line,
Another, much looooooonger line of text and/or sentence"""
d = DocumentWrapper(width=50)
print(d.fill(text))
# First line,
# Another, much looooooonger line of text and/or
# sentence
Questo è un bell’esempio di modifica del file wrap
metodo per preservare le interruzioni di riga esistenti e stamparle correttamente.
Per un esempio più completo per la gestione di più paragrafi con TextWrapper
guardare Questo articolo.
Finalmente, textwrap
include anche due funzioni per il rientro, la prima delle quali è dedent
:
# Ugly formatting:
multiline_string = """
First line
Second line
Third line
"""from textwrap import dedent
multiline_string = """
First line
Second line
Third line
"""
print(dedent(multiline_string))
# First line
# Second line
# Third line
# Notice the leading blank line...
# You can use:
multiline_string = """\
First line
Second line
Third line
"""
# or
from inspect import cleandoc
cleandoc(multiline_string)
# 'First line\nSecond line\nThird line'
Per impostazione predefinita, le stringhe multilinea in Python rispettano qualsiasi rientro utilizzato nella stringa, quindi dobbiamo utilizzare la brutta formattazione mostrata nella prima variabile nello snippet sopra. Ma possiamo usare il dedent
per migliorare la formattazione: rientriamo semplicemente il valore della variabile come preferiamo e poi chiamiamo dedent
su di esso prima di utilizzarlo.
In alternativa, potremmo anche usare inspect.cleandoc
che rimuove anche il ritorno a capo iniziale. Questa funzione tuttavia codifica gli spazi bianchi come caratteri speciali (\n
E \t
), quindi potrebbe essere necessario riformattarlo di nuovo.
Naturalmente, quando c’è dedent
allora deve esserci anche indent
funzione:
from textwrap import indentindented = indent(text, " ", lambda x: not text.splitlines()(0) in x)
Forniamo semplicemente il testo e la stringa con cui verrà rientrata ogni riga (qui solo 4 spazi, potremmo — ad esempio — usare >>>
per farlo sembrare REPL). Inoltre, possiamo fornire un predicato che deciderà se la riga dovrà essere rientrata o meno. Nell’esempio sopra, il lambda
la funzione fa in modo che la prima riga della stringa (paragrafo) non sia rientrata.
textwrap
è un modulo semplice con solo poche funzioni/metodi, ma dimostra ancora una volta che Python è davvero dotato “batterie incluse” per cose che non devono necessariamente essere librerie standard, ma possono farti risparmiare così tanto tempo quando ne hai bisogno.
Se ti capita di elaborare molto testo, ti consiglio anche di dare un’occhiata a intera sezione documenti dedicato a lavorare con il testo. Ci sono molti altri moduli e piccole funzioni di cui non sapevi di aver bisogno. 😉
Questo articolo è stato originariamente pubblicato su martinheinz.dev
Fonte: towardsdatascience.com