Formatowanie ciągów znaków w Pythonie 3

114

Robię to w Pythonie 2:

"(%d goals, $%d)" % (self.goals, self.penalties)

Jaka jest wersja tego Pythona 3?

Próbowałem szukać przykładów w Internecie, ale nadal otrzymywałem wersje Pythona 2.

JoseBazBaz
źródło
Nie został wycofany; twój kod działa dobrze. Przeczytaj więcej tutaj .
jackcogdill
32
Uwaga dla zwykłego czytelnika: znak dolara nie ma specjalnego znaczenia. Tutaj jest tylko znak dolara. (Dzięki Martijn Pieters)
kevinarpe
1
pyformat.info i python-course.eu/python3_formatted_output.php (Nie moje strony)
Christophe Roussy
1
Znak dolara sprawił, że było to bardzo zagmatwane ...
cchamberlain

Odpowiedzi:

173

Oto dokumenty dotyczące „nowej” składni formatu. Przykładem może być:

"({:d} goals, ${:d})".format(self.goals, self.penalties)

Jeśli oba goalsi penaltiessą liczbami całkowitymi (tj. Ich domyślny format jest w porządku), można go skrócić do:

"({} goals, ${})".format(self.goals, self.penalties)

A ponieważ parametry są polami typu self, istnieje również sposób, aby zrobić to za pomocą pojedynczego argumentu dwukrotnie (jak @Burhan Khalid zauważył w komentarzach):

"({0.goals} goals, ${0.penalties})".format(self)

Wyjaśnienie:

  • {} oznacza tylko następny argument pozycyjny, z domyślnym formatem;
  • {0}oznacza argument z indeksem 0, z domyślnym formatem;
  • {:d} jest kolejnym argumentem pozycyjnym w formacie dziesiętnej liczby całkowitej;
  • {0:d}jest argumentem z indeksem 0, z dziesiętną liczbą całkowitą.

Istnieje wiele innych rzeczy, które możesz zrobić, wybierając argument (używając nazwanych argumentów zamiast pozycyjnych, uzyskując dostęp do pól itp.), A także wiele opcji formatowania (uzupełnianie liczby, użycie separatorów tysięcy, wyświetlanie znaku lub nie itp.). Kilka innych przykładów:

"({goals} goals, ${penalties})".format(goals=2, penalties=4)
"({goals} goals, ${penalties})".format(**self.__dict__)

"first goal: {0.goal_list[0]}".format(self)
"second goal: {.goal_list[1]}".format(self)

"conversion rate: {:.2f}".format(self.goals / self.shots) # '0.20'
"conversion rate: {:.2%}".format(self.goals / self.shots) # '20.45%'
"conversion rate: {:.0%}".format(self.goals / self.shots) # '20%'

"self: {!s}".format(self) # 'Player: Bob'
"self: {!r}".format(self) # '<__main__.Player instance at 0x00BF7260>'

"games: {:>3}".format(player1.games)  # 'games: 123'
"games: {:>3}".format(player2.games)  # 'games:   4'
"games: {:0>3}".format(player2.games) # 'games: 004'

Uwaga: Jak zauważyli inni, nowy format nie zastępuje poprzedniego, oba są dostępne zarówno w Pythonie 3, jak i nowszych wersjach Pythona 2. Niektórzy mogą powiedzieć, że to kwestia preferencji, ale IMHO nowszy jest znacznie bardziej wyrazisty niż starszy i powinien być używany przy każdym pisaniu nowego kodu (chyba że jest przeznaczony dla starszych środowisk, oczywiście).

mgibsonbr
źródło
9
Możesz też to zrobić"({0.goals} goals, ${0.penalties})".format(self)
Burhan Khalid,
Musisz wziąć „%” poza nawiasy klamrowe, np. {: .2f%} -> {: .2f}%
SuperElectric
@SuperElectric znaczy w tej linii: "conversion rate: {:.2%}".format(self.goals / self.shots)? U mnie działa dobrze, ponieważ jest ... (Python 3.4) Zauważ, że nie ma fw tym nic, proszę o formatowanie jako procent, a nie jako liczba zmiennoprzecinkowa.
mgibsonbr
Masz rację; wygląda na to, że działa w Pythonie 3.4, więc jest w porządku, ponieważ OP pytał o Python3. Właśnie stwierdziłem, że nie działa z Pythonem 2.7.6. "{:.2f}%".format(float_num)działa dobrze dla obu.
SuperElectric
1
@JohnSchmitt Tak, ten przykład miał dawać dokładnie takie same dane wyjściowe jak kod podany w pytaniu. Nie $ma tutaj specjalnego znaczenia, ani w starej składni formatu, ani w nowej, dlatego powinno być obecne w wygenerowanym ciągu niezmienione.
mgibsonbr
67

Python 3.6 obsługuje teraz skróconą interpolację literału ciągów w PEP 498 . W twoim przypadku nowa składnia jest po prostu:

f"({self.goals} goals, ${self.penalties})"

Jest to podobne do poprzedniego .formatstandardu, ale pozwala łatwo robić takie rzeczy, jak :

>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal('12.34567')
>>> f'result: {value:{width}.{precision}}'
'result:      12.35'
JDong
źródło
12

Ta linia działa tak, jak jest w Pythonie 3.

>>> sys.version
'3.2 (r32:88445, Oct 20 2012, 14:09:29) \n[GCC 4.5.2]'
>>> "(%d goals, $%d)" % (self.goals, self.penalties)
'(1 goals, $2)'
Mark Reed
źródło
DOBRZE. CHŁODNY. Po wysłaniu pytania kontynuowałem wyszukiwanie i stwierdziłem, że musimy wykonać {% d} zamiast tylko% d, czy to też jest poprawne? A może sposób w Pythonie2 jest jedynym sposobem, aby to zrobić?
JoseBazBaz,
2
Python 3 wprowadza nową składnię - to nawiasy klamrowe - ale nie musisz jej używać. Możesz użyć starego lub nowego. Ale są różne; jeśli używasz curlies, nie używasz znaków procentu.
Mark Reed,
2

Podoba mi się to podejście

my_hash = {}
my_hash["goals"] = 3 #to show number
my_hash["penalties"] = "5" #to show string
print("I scored %(goals)d goals and took %(penalties)s penalties" % my_hash)

Zwróć uwagę na odpowiednio dołączone d i s do nawiasów.

wynik będzie:

I scored 3 goals and took 5 penalties
fullstacklife
źródło