String formatting in Python: can I use %s for all types?

16,303

Solution 1

using %s automatically calls str on the variable. Since everything has __str__ defined, you should be able to do this without a problem (i.e. no exception will be raised). However, what you actually will have printed is another story ...

Note that in newer python code, there's another option which uses the format method:

'Integer: {}; Float: {}; String: {}'.format(a,b,c)

This works basically the same way except that it is more powerful once you learn the syntax.

Solution 2

Yes, that is exactly what %s means; convert the argument to a string and interpolate it.

You can also specify other forms of conversion, such as %d and %f to convert values to different types of representations. See String Formatting Operations for more details.

As an alternative, as of Python 2.6 and up you can also use a different form of string formatting using the .format() method:

print 'Integer: {0}; Float: {1}; String: {2}'.format(a, b, c)

That method offers some extra features, such as referring to attributes of objects, keys in a mapping or indexes in a list to refer to values.

Solution 3

Another option is to use new style string formatting - which behaves the same way.

>>> 'integer: {} float: {} string: {}'.format(1, 1.1, 'blah')
'integer: 1 float: 1.1 string: blah'

However, it also means you can instead of writing str(obj) do instead:

>>> format(1)
'1'
>>> format(1.1)
'1.1'
>>> format('blah')
'blah'

And then, you could supply a formatting option to it:

>>> format(12345, '>10,')
'    12,345'

Solution 4

The reason there are other operators than %s is to provide specific formatting functionality for the datatypes they operate on.

When you use %s, all you get is the result of calling str() on the value to interpolate.

So, using %s means you would be unable to force the representation of the value to conform to the strict formatting you may want to use, because you are stuck with the output of str().

Using the other operators, it is possible to specify a format for the value. IE: perhaps you wish to have all floating point numbers in the string represented to 2 decimal places regardless of the actual number of decimal places the number requires - for this case %s just would not do the job.

Share:
16,303
Ricky Robinson
Author by

Ricky Robinson

Updated on June 04, 2022

Comments

  • Ricky Robinson
    Ricky Robinson almost 2 years

    When doing string formatting in Python, I noticed that %s transforms also numbers to strings.

    >>> a = 1
    >>> b = 1.1
    >>> c = 'hello'
    >>> print 'Integer: %s; Float: %s; String: %s' % (a, b, c)
    Integer: 1; Float: 1.1; String: hello
    

    I don't know for other variable types, but is it safe to use %s like this?

    It is certainly quicker than specifying always the type each time.

  • Ricky Robinson
    Ricky Robinson over 11 years
    Cool. So why should I ever use %i or %f?
  • mgilson
    mgilson over 11 years
    @RickyRobinson -- They allow for more fine-grained control over how the number is printed. If you want your integer to always take 6 spaces in the output string, then you need '%6i' or '%6d' -- I've actually never used %i before ...
  • Admin
    Admin over 11 years
    @RickyRobinson More self-documenting code, an error (instead of a silently wrong program) if the parameter's not what you expect, more powerful formatting options.
  • Ricky Robinson
    Ricky Robinson over 11 years
    Ok. I didn't get what the disadvantages of using %s for all types are. You mentioned that something might happen when printing. What might happen?
  • mgilson
    mgilson over 11 years
    Consider if you create a class class foo: pass -- Then you create an instance of it: a = foo(). Then you put it in a string: '%s'%(foo) -- What will you get? I get '__main__.foo' ... which is probably not what you wanted ...
  • mgilson
    mgilson over 11 years
    I think I'm ahead of you by about 2 seconds today (probably the amount of time it takes you to find the links and add them)
  • Martijn Pieters
    Martijn Pieters over 11 years
    @mgilson: I am holding multiple conversations at once at the moment. Does that count for anything? :-P
  • Ricky Robinson
    Ricky Robinson over 11 years
    Oh but why would I ever want to print a class constructor?
  • mgilson
    mgilson over 11 years
    @RickyRobinson -- You can do lots of things in python -- It's not up to me to tell you what to use it for ;-). The point is that you gain more control over the output if you use the proper '%...' option. If you don't know the type though, you can use %, just don't expect the output to be formatted in an exact manner (e.g. 3 spaces followed by a number 8 characters wide followed by a float with 3 spaces after the decimal point ...)
  • mgilson
    mgilson over 11 years
    Why can't you just let me feel good about myself for getting an answer in there ahead of you for once? :-P
  • Martijn Pieters
    Martijn Pieters over 11 years
    @mgilson: :-P Congrats on not only answering first, but getting it accepted too! BTW, when will we see you join the python chat room? There you can boast and feel good all the time!