web-dev-qa-db-fra.com

sprintf comme fonctionnalité en Python

Je voudrais créer un tampon de chaîne pour effectuer beaucoup de traitement, formater et enfin écrire le tampon dans un fichier texte en utilisant une fonctionnalité sprintf de style C en Python. En raison des instructions conditionnelles, je ne peux pas les écrire directement dans le fichier.

par exemple, pseudo-code:

sprintf(buf,"A = %d\n , B= %s\n",A,B)
/* some processing */
sprint(buf,"C=%d\n",c)
....
...
fprintf(file,buf)

Donc, dans le fichier de sortie, nous avons ce genre de o/p:

A= foo B= bar
C= ded
etc...

Modifier, pour clarifier ma question:
buf est un grand tampon qui contient toutes ces chaînes qui ont été formatées avec sprintf. Selon vos exemples, buf ne contiendra que les valeurs actuelles, pas les plus anciennes. Par exemple, premier dans buf j'ai écrit A= something ,B= something plus tard C= something a été ajouté dans la même buf, mais dans vos réponses Python, buf ne contient que la dernière valeur, ce que je ne veux pas - je veux que buf ait tous les printfs que j'ai faits depuis le début, comme dans C.

105
spring

Python a un opérateur % pour cela.

>>> a = 5
>>> b = "hello"
>>> buf = "A = %d\n , B = %s\n" % (a, b)
>>> print buf
A = 5
 , B = hello

>>> c = 10
>>> buf = "C = %d\n" % c
>>> print buf
C = 10

Voir cette référence pour tous les spécificateurs de format pris en charge.

Vous pouvez aussi bien utiliser format :

>>> print "This is the {}th tome of {}".format(5, "knowledge")
This is the 5th tome of knowledge
142
Alexei Sholik

Si je comprends bien votre question, format () est ce que vous recherchez, avec son mini-langage .

Exemple idiot pour Python 2.7 et plus:

>>> print "{} ...\r\n {}!".format("Hello", "world")
Hello ...
 world!

Pour les versions antérieures de Python: (testé avec 2.6.2)

>>> print "{0} ...\r\n {1}!".format("Hello", "world")
Hello ...
 world!
34
Nicolas Lefebvre

Je ne suis pas tout à fait sûr de comprendre votre objectif, mais vous pouvez utiliser une instance StringIO comme tampon:

>>> import StringIO 
>>> buf = StringIO.StringIO()
>>> buf.write("A = %d, B = %s\n" % (3, "bar"))
>>> buf.write("C=%d\n" % 5)
>>> print(buf.getvalue())
A = 3, B = bar
C=5

Contrairement à sprintf, vous passez simplement une chaîne à buf.write en la formatant avec l'opérateur % ou la méthode format de chaînes. 

Vous pouvez bien sûr définir une fonction pour obtenir l'interface sprintf que vous espérez:

def sprintf(buf, fmt, *args):
    buf.write(fmt % args)

qui serait utilisé comme ceci:

>>> buf = StringIO.StringIO()
>>> sprintf(buf, "A = %d, B = %s\n", 3, "foo")
>>> sprintf(buf, "C = %d\n", 5)
>>> print(buf.getvalue())
A = 3, B = foo
C = 5
14
Michael J. Barber

Utilisez l'opérateur de mise en forme % :

buf = "A = %d\n , B= %s\n" % (a, b)
print >>f, buf
10
NPE

Vous pouvez utiliser le formatage de chaîne:

>>> a=42
>>> b="bar"
>>> "The number is %d and the Word is %s" % (a,b)
'The number is 42 and the Word is bar'

Mais ceci est supprimé dans Python 3, vous devriez utiliser "str.format ()":

>>> a=42
>>> b="bar"
>>> "The number is {0} and the Word is {1}".format(a,b)
'The number is 42 and the Word is bar'
9
utdemir

Pour insérer dans une très longue chaîne, il est agréable d'utiliser des noms pour les différents arguments, au lieu d'espérer qu'ils sont dans les bonnes positions. Cela facilite également le remplacement de plusieurs récurrences.

>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
'Coordinates: 37.24N, -115.81W'

Tiré de Exemples de format , où toutes les autres réponses liées à Format- sont également affichées.

6
Jost

C’est probablement la traduction la plus proche de votre code C en code Python.

A = 1
B = "hello"
buf = "A = %d\n , B= %s\n" % (A, B)

c = 2
buf += "C=%d\n" % c

f = open('output.txt', 'w')
print >> f, c
f.close()

L'opérateur % dans Python fait presque exactement la même chose que la variable sprintf de C. Vous pouvez également imprimer la chaîne dans un fichier directement. Si de nombreux stringlets au format chaîne sont impliqués, il peut être judicieux d’utiliser un objet StringIO pour accélérer le traitement.

Donc au lieu de faire +=, faites ceci:

import cStringIO
buf = cStringIO.StringIO()

...

print >> buf, "A = %d\n , B= %s\n" % (A, B)

...

print >> buf, "C=%d\n" % c

...

print >> f, buf.getvalue()
3
Y.H Wong

Si vous voulez quelque chose comme la fonction d’impression python3 mais avec une chaîne:

def sprint(*args, **kwargs):
    sio = io.StringIO()
    print(*args, **kwargs, file=sio)
    return sio.getvalue()
>>> x = sprint('abc', 10, ['one', 'two'], {'a': 1, 'b': 2}, {1, 2, 3})
>>> x
"abc 10 ['one', 'two'] {'a': 1, 'b': 2} {1, 2, 3}\n"

ou sans le '\n' à la fin:

def sprint(*args, end='', **kwargs):
    sio = io.StringIO()
    print(*args, **kwargs, end=end, file=sio)
    return sio.getvalue()
>>> x = sprint('abc', 10, ['one', 'two'], {'a': 1, 'b': 2}, {1, 2, 3})
>>> x
"abc 10 ['one', 'two'] {'a': 1, 'b': 2} {1, 2, 3}"
0
Michael

Jetez un coup d’œil à "Interpolation de chaînes littérales" https://www.python.org/dev/peps/pep-0498/

Je l'ai trouvé à travers le http://www.malemburg.com/

0
Andrei Sura

Selon (cette comparaison de performances), la compréhension de liste est votre option la plus rapide. Voici une implémentation orientée objet, qui utilise l'interpolation de chaîne littérale (également appelée f-String) introduite dans python 3.6:


class Buffer:
    _buf = []

    def sprintf(self,s):
      self._buf.append(s)

    def fprintf(self,filename):
        with open(filename,'w+') as file:
            file.write(''.join([self._buf[i] for i in range(len(self._buf)) ]))


def testBuffer():
    A = 1
    B = "Hello"
    C = "World"
    buf = Buffer()
    buf.sprintf("A = {A}\n , B = {B}\n")
    buf.sprintf("C = {C}\n")
    buf.fprintf("output.txt")


testBuffer()
0
Mohamed El-Nakeep

Quelque chose comme...

name = "John"

print("Hello %s", name)

Hello John
0
bmatovu