Pour commencer, je cherche à obtenir une sortie désirée comme ceci:
*********************************************************************
hello
*********************************************************************
Pour ce faire, j'ai assigné le sortie désirée à une variable avec une chaîne multiligne et je l'ai imprimé avec le format.
$ cat varibale.py
decorator = """ **********************************************************************
{}
********************************************************************** """
print(decorator.format("hello"))
Sortie:
**********************************************************************
hello
**********************************************************************
Le problème avec l'approche ci-dessus est le espaces supplémentaires dans la troisième ligne de sortie qui semble étrange.
Je suis capable d'y parvenir de la manière suivante:
$ cat varibale.py
decorator = """ **********************************************************************
{}
*********************************************************************
"""
print(decorator.format("hello"))
Sortie:
**********************************************************************
hello
*********************************************************************
Mais de cette façon, mon code n’a pas l’air beau, car il ne suit pas l’indentation.
Veuillez suggérer le bon moyen d’atteindre le résultat souhaité.
Une façon de rendre les chaînes littérales multilignes jolies consiste à utiliser une barre oblique inverse pour échapper à la nouvelle ligne, comme ceci:
s = '''\
*********************************************************************
hello
*********************************************************************
'''
print(s)
sortie
*********************************************************************
hello
*********************************************************************
Cependant, PEP-008 décourage l'utilisation d'une barre oblique inversée comme celle-là. C'est trop fragile: s'il y a un espace entre la barre oblique inverse et la nouvelle ligne, celle-ci ne sera pas échappée et la barre oblique inverse sera imprimée.
Une approche plus polyvalente consiste à utiliser une fonction qui calcule la quantité de remplissage requise pour centrer le texte et l'applique via un spécificateur de mise en forme imbriqué. Par exemple:
def banner(s, width=69):
stars = '*' * width
pad = (width + len(s)) // 2
return '{0}\n{1:>{2}}\n{0}'.format(stars, s, pad)
print(banner('hello'))
print(banner('Hello, world', width=16))
sortie
*********************************************************************
hello
*********************************************************************
****************
Hello, world
****************
Cette chaîne de format est un peu dense, alors je suppose que je devrais essayer de l'expliquer. ;) Pour obtenir des informations complètes sur ce sujet, veuillez consulter Format Syntaxe des chaînes dans les documents. L'explication ci-dessous emprunte & paraphrase ces documents.
'{0}\n{1:>{2}}\n{0}'.format(stars, s, pad)
La substance incluse dans {}
dans une chaîne de format s'appelle un "champ de remplacement". Le premier élément d'un champ de remplacement est le nom du champ facultatif. Cela nous permet d'identifier l'argument de .format
associé à ce champ de remplacement. Il existe plusieurs variantes possibles pour les noms de champ. Cette chaîne de format utilise des noms numériques, de sorte qu'elle identifie les arguments .format
par leur position. Autrement dit, 0 correspond à stars
, 1 correspond à s
et 2 correspond à pad
.
Si aucun nom de champ n'est donné, ils sont automatiquement renseignés par les chiffres 0, 1, 2, ... etc. (sauf si vous utilisez Python 2.6, où les noms de champ sont obligatoires). C'est très utile la plupart du temps, donc la plupart des chaînes de format ne s'embêtent pas à utiliser des noms de champs.
Après le nom du champ, nous pouvons donner un "spécificateur de format" ou une "spécification de format" qui décrit comment la valeur doit être présentée. Un deux-points :
sépare le nom du champ de la spécification de format. Si vous ne fournissez pas de spécification de format, vous en obtenez une par défaut, ce qui est généralement suffisant. Mais ici, nous voulons un peu plus de contrôle, nous devons donc fournir une spécification de format.
Dans une spécification de formulaire, le signe >
force le champ à être aligné à droite dans l'espace disponible. Après le signe d’alignement, nous pouvons fournir un numéro pour spécifier la largeur minimale du champ; le champ sera automatiquement agrandi si nécessaire.
Par exemple, '{0:>6}'.format('test')
dit de mettre l'argument 0 ('test') dans un espace large d'au moins 6 caractères, aligné à droite. Ce qui donne la chaîne ' test'
.
Mais une spécification de format peut en réalité contenir un tout nouveau champ de remplacement! Cela nous permet de fournir une variable pour contrôler la largeur du champ. Donc, dans mon format, la chaîne {1:>{2}}
dit de mettre arg 1 ici (s
), aligné à droite dans un champ de largeur donnée par arg 2 (pad
). Un seul niveau d'imbrication de champ de remplacement est autorisé, mais il est difficile d'imaginer une situation dans laquelle vous souhaiteriez réellement une imbrication plus profonde.
Donc, assembler le tout: '{0}\n{1:>{2}}\n{0}'
indique à .format
de construire une chaîne commençant par arg 0 (stars
) en utilisant la spécification de format par défaut, suivie d'une nouvelle ligne, suivie de arg 1 (s
) aligné à droite dans un champ de largeur pad
, suivi de une autre nouvelle ligne, suivie de nouveau par arg 0 (stars
).
J'espère que cela a eu assez de sens. :)
Dans Python 3.6+, nous pourrions utiliser une chaîne f:
def banner(s, width=69):
stars = '*' * width
pad = (width + len(s)) // 2
return f'{stars}\n{s:>{pad}}\n{stars}'
vous pouvez procéder par exemple comme:
print('*'*80)
print('{msg:^80s}'.format(msg = 'HELLO')) #^ centers the message
print('*'*80)
ou si vous voulez avoir la dynamique text-width:
def fn(msg, w = 80):
delim = '*'*w
fmt = '{msg:^%ds}'%w
print(delim)
print(fmt.format(msg=msg))
print(delim)
fn('hello')
ou une version légèrement généralisée si vous avez besoin d'écrire dans un fichier:
import sys
def fn(msg, w = 80, F = sys.stdout):
delim = '*'*w
fmt = '{delim:s}\n{msg:^%ds}\n{delim:s}\n'%w
F.write(fmt.format(delim = delim, msg = msg))
fn('hello')
Peut être :
print '*' * 80 + '\n' + ' ' * 38 + 'hello' + '\n' + '*' *80
OU S'il s'agit de python3
a = lambda x,c,mess: print(c*x + ('\n' if not mess else mess))
a(80, '*', None)
a(38, ' ', 'Hello')
a(80, '*', None)
Une autre solution consisterait à utiliser le module textwrap
import textwrap
decorator = """\
****
{0}
****"""
print(textwrap.dedent(decorator.format("hello")))