0

I am learning the Python string format() method. Though I understand that {} is a placeholder for arguments, I am not sure what : represent in the following code snippet from Programiz tutorial:

import datetime # datetime formatting date = datetime.datetime.now() print("It's now: {:%Y/%m/%d %H:%M:%S}".format(date)) # custom __format__() method class Person: def __format__(self, format): if(format == 'age'): return '23' return 'None' print("Adam's age is: {:age}".format(Person())) 
  1. Why is there a : in front of %Y in print("It's now: {:%Y/%m/%d...? The code outputs It's now: 2021, and there is no : in front of 2021.
  2. Why is there a : in front of age in print("Adam's age is: {:age}...?

Thanks in advance for your valuable input!!

1
  • Hmm, interesting question. my underestanding is the : in front of an argument calls the __format__ method of the object that you pass in to format. Commented Oct 4, 2021 at 17:00

3 Answers 3

2

Everything after : is a parameter to the __format__() method of the class of the corresponding arguent. For instance, for a number you can write {:.2f} to format it as a decimal number with 2 digits of precision after the decimal point.

For a datetime value, it's a format string that could be used with datetime.strftime().

And in your Person class, it will be passed as the format argument to Person.__format__(). So if you don't put :age there, the if condition will fail and it will print None instead of 23.

Sign up to request clarification or add additional context in comments.

Comments

0

Python objects decide for themselves how they should be formatted using the __format__ method. Mostly we just use the defaults that come with the basic types, but much like __str__ and __repr__ we can customize. The stuff after the colon : is the parameter to __format__.

>>> class Foo: ... def __format__(self, spec): ... print(repr(spec)) ... return "I will stubbornly refuse your format" ... >>> f = Foo() >>> print("Its now {:myformat}".format(f)) 'myformat' Its now I will stubbornly refuse your format 

we can call the formatter ourselves. datetime uses the strftime format rules.

>>> import datetime >>> # datetime formatting >>> date = datetime.datetime.now() >>> print("It's now: {:%Y/%m/%d %H:%M:%S}".format(date)) It's now: 2021/10/04 11:12:23 >>> date.__format__(":%Y/%m/%d %H:%M:%S") ':2021/10/04 11:12:23' 

Your custom Person class implemented __format__ and used the format specifier after the colon to return a value.

Comments

0

Try f-strings. In them the colon seems to be more reasonable. It delimits the variable name and its formatting options:

import datetime # datetime formatting date = datetime.datetime.now() print(f"It's now: {date:%Y/%m/%d %H:%M:%S}") # custom __format__() method class Person: def __format__(self, format): if(format == 'age'): return '23' return 'None' print(f"Adam's age is: {Person():age}") 

Btw you can have similar functionality with keyword arguments to format():

print("It's now: {d:%Y/%m/%d %H:%M:%S}".format(d=date)) print("Adam's age is: {adam:age}".format(adam=Person())) 

5 Comments

This is really cool! I tried with f-strings actually but i didn't know it supported format method. The :age part is I think what I was missing.
Names work with .format also - its the name of the format keyword argument.print("It's now: {mydate:%Y/%m/%d %H:%M:%S}".format(mydate=date))
@tdelaney Thank you for your comment, but it's not that I didn't mention it in my answer.
@AntonyHatchkins - names have been a part of .format since its creation. Its not a forward compatibility thing. There is a big difference. With f-strings, its a name in the containing namespace. With .format, its a keyword argument name.
@tdelaney .format itself is a forward compatibility thing in respect to f-strings.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.