Używanie wielu argumentów do formatowania ciągów znaków w Pythonie (np. „% S…% s”)


174

Mam ciąg, który wygląda jak '%s in %s'i chcę wiedzieć, jak oddzielić argumenty, aby były dwoma różnymi% s. Mój umysł pochodzący z Javy wymyślił to:

'%s in %s' % unicode(self.author),  unicode(self.publication)

Ale to nie działa, więc jak to wygląda w Pythonie?

Odpowiedzi:


191

Odpowiedź Marka Cidade jest prawidłowa - musisz podać krotkę.

Jednak począwszy od Pythona 2.6 możesz używać formatzamiast %:

'{0} in {1}'.format(unicode(self.author,'utf-8'),  unicode(self.publication,'utf-8'))

%Nie zaleca się już używania do formatowania ciągów.

Ta metoda formatowania ciągów jest nowym standardem w Pythonie 3.0 i powinna być preferowana względem formatowania% opisanego w operacjach formatowania ciągów w nowym kodzie.


5
Również zaczynając od Pythona 2.7 może porzucić numer indeksu, tj. Użyć prostego '{} in {}'ciągu formatu.
Cristian Ciupitu

121

Jeśli używasz więcej niż jednego argumentu, musi on znajdować się w krotce (zwróć uwagę na dodatkowe nawiasy):

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Jak wskazuje EOL, unicode()funkcja zwykle przyjmuje domyślnie kodowanie ascii, więc jeśli masz znaki inne niż ASCII, bezpieczniej jest jawnie przekazać kodowanie:

'%s in %s' % (unicode(self.author,'utf-8'),  unicode(self.publication('utf-8')))

Od wersji Python 3.0 lepiej jest używać str.format()składni:

'{0} in {1}'.format(unicode(self.author,'utf-8'),unicode(self.publication,'utf-8'))

60

W obiekcie krotki / mapowania dla wielu argumentów format

Poniżej znajduje się wyciąg z dokumentacji:

Biorąc pod uwagę format % values, %specyfikacje konwersji w formatsą zastępowane przez zero lub więcej elementów values. Efekt jest podobny do użycia sprintf()w języku C.

Jeśli formatwymaga jednego argumentu, wartości mogą być pojedynczym obiektem niebędącym krotką. W przeciwnym razie wartości muszą być krotką z dokładnie taką liczbą elementów, jaką określa formatciąg , lub pojedynczym obiektem mapowania (na przykład słownikiem).

Bibliografia


On str.formatzamiast%

Nowszą alternatywą dla %operatora jest użycie str.format. Oto fragment dokumentacji:

str.format(*args, **kwargs)

Wykonaj operację formatowania ciągu. Ciąg, w którym ta metoda jest wywoływana, może zawierać tekst literału lub pola zastępcze rozdzielone nawiasami klamrowymi {}. Każde pole zastępcze zawiera indeks numeryczny argumentu pozycyjnego lub nazwę argumentu słowa kluczowego. Zwraca kopię ciągu, w którym każde pole zastępcze jest zastępowane wartością ciągu odpowiadającego mu argumentu.

Ta metoda jest nowym standardem w Pythonie 3.0 i powinna być preferowana do %formatowania .

Bibliografia


Przykłady

Oto kilka przykładów użycia:

>>> '%s for %s' % ("tit", "tat")
tit for tat

>>> '{} and {}'.format("chicken", "waffles")
chicken and waffles

>>> '%(last)s, %(first)s %(last)s' % {'first': "James", 'last': "Bond"}
Bond, James Bond

>>> '{last}, {first} {last}'.format(first="James", last="Bond")
Bond, James Bond

Zobacz też


Nie mam sposobu, aby to przetestować (nie znam za dużo Pythona), ale przykłady wydają się sugerować, że coś takiego '{self.author} in {self.publication}'.format(self=self)powinno „działać”. Po prostu nie jestem pewien co do całości unicode.
polygenelubricants

1
Tak, rzeczywiście możesz uzyskać dostęp do atrybutów (a także indeksów). Zobacz docs.python.org/library/string.html#formatstrings Więc w swoim przykładzie mogłeś użyć {first[0]}do uzyskania inicjału J.
Duncan

10

Musisz po prostu umieścić wartości w nawiasach:

'%s in %s' % (unicode(self.author),  unicode(self.publication))

Tutaj po raz pierwszy zostaną umieszczone. Po drugie , zostanie użyty.%sunicode(self.author)%sunicode(self.publication)

Uwaga: Należy sprzyjać string formattingnad% Notation. Więcej informacji tutaj


Nie mogę uwierzyć, że ludzie nadal %sraczej sugerująformat
user1767754

8

Z niektórymi dotychczas opublikowanymi odpowiedziami jest poważny problem: unicode()dekoduje z domyślnego kodowania, którym często jest ASCII; w rzeczywistości unicode()próbuje nadać sens bajtom, które otrzymuje, konwertując je na znaki. W związku z tym następujący kod, który zasadniczo jest zalecany we wcześniejszych odpowiedziach, nie działa na moim komputerze:

# -*- coding: utf-8 -*-
author = 'éric'
print '{0}'.format(unicode(author))

daje:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print '{0}'.format(unicode(author))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

Niepowodzenie wynika z faktu, że authornie zawiera tylko bajtów ASCII (tj. Z wartościami w [0; 127]) i unicode()domyślnie dekoduje z ASCII (na wielu komputerach).

Solidnym rozwiązaniem jest jawne podanie kodowania używanego w twoich polach; biorąc jako przykład UTF-8:

u'{0} in {1}'.format(unicode(self.author, 'utf-8'), unicode(self.publication, 'utf-8'))

(lub bez inicjału u, w zależności od tego, czy chcesz uzyskać wynik Unicode, czy ciąg bajtów).

W tym momencie można rozważyć, authorczy publicationpola i są ciągami znaków Unicode, zamiast dekodować je podczas formatowania.


5

W przypadku python2 możesz to również zrobić

'%(author)s in %(publication)s'%{'author':unicode(self.author),
                                  'publication':unicode(self.publication)}

co jest przydatne, jeśli masz wiele argumentów do zastąpienia (szczególnie jeśli zajmujesz się internacjonalizacją)

Python2.6 i nowsze obsługują .format()

'{author} in {publication}'.format(author=self.author,
                                   publication=self.publication)

4

Możesz również użyć go w sposób czysty i prosty (ale źle! Ponieważ powinieneś używać go formattak, jak powiedział Mark Byers), wykonując:

print 'This is my %s formatted with %d arguments' % ('string', 2)

3

Dla kompletności, w Pythonie 3.6 f-string zostały wprowadzone w PEP-498 . Te struny umożliwiają

osadzanie wyrażeń w literałach ciągów przy użyciu minimalnej składni.

Oznaczałoby to, że na przykład możesz również użyć:

f'{self.author} in {self.publication}'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.