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 printf
s que j'ai faits depuis le début, comme dans C
.
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
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!
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
Utilisez l'opérateur de mise en forme %
:
buf = "A = %d\n , B= %s\n" % (a, b)
print >>f, buf
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'
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.
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()
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}"
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/
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()
Quelque chose comme...
name = "John"
print("Hello %s", name)
Hello John