209

What does %s mean in Python? And what does the following bit of code do?

For instance...

 if len(sys.argv) < 2:
     sys.exit('Usage: %s database-name' % sys.argv[0])

 if not os.path.exists(sys.argv[1]):
     sys.exit('ERROR: Database %s was not found!' % sys.argv[1])
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tyler
  • 3,919
  • 7
  • 27
  • 26
  • 5
    The `%` operator is deprecated in favor of the more powerful `str.format` method, see [PEP-3101](http://docs.python.org/3.1/whatsnew/2.6.html#pep-3101). – Paulo Scardine Jul 17 '13 at 17:37
  • 50
    Actually that PEP says "In Python 3.0, the % operator is supplemented by a more powerful string formatting method" and that it is backported to Python 2.6. Where I come from "supplemented" means added to, not replaced. The PEP does not say "supplanted" and in no part of the PEP does it say the % operator is deprecated (yet it does say other things are deprecated down the bottom). You might prefer str.format and that's fine, but until there's a PEP saying it is deprecated there's no sense in claiming it is when it isn't. – Ben Oct 29 '13 at 08:07

7 Answers7

248

It is a string formatting syntax (which it borrows from C).

Please see "PyFormat":

Python supports formatting values into strings. Although this can include very complicated expressions, the most basic usage is to insert values into a string with the %s placeholder.

Here is a really simple example:

#Python 2
name = raw_input("who are you? ")
print "hello %s" % (name,)

#Python 3+
name = input("who are you? ")
print("hello %s" % (name,))

The %s token allows me to insert (and potentially format) a string. Notice that the %s token is replaced by whatever I pass to the string after the % symbol. Notice also that I am using a tuple here as well (when you only have one string using a tuple is optional) to illustrate that multiple strings can be inserted and formatted in one statement.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
153

Andrew's answer is good.

And just to help you out a bit more, here's how you use multiple formatting in one string:

"Hello %s, my name is %s" % ('john', 'mike') # Hello john, my name is mike".

If you are using ints instead of string, use %d instead of %s.

"My name is %s and I'm %d" % ('john', 12) #My name is john and I'm 12
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sqram
  • 7,069
  • 8
  • 48
  • 66
  • 2
    nice. %d saves you from casting str(int). any idea what the %s and %d stand for? i guess i'll remember them as string and digit. – user391339 Apr 03 '16 at 19:29
  • 5
    @user391339 stands for decimal :) they're all here https://docs.python.org/2/library/stdtypes.html#string-formatting-operations – sqram Apr 04 '16 at 04:47
  • 1
    I don't know for earlier versions, but at least for 3.6 it works the same even if you use `%s` on integers, it will just be converted into a string. – lapin Mar 21 '20 at 01:15
  • 1
    @lapin you are correct :) . but that may not always be what you want. Say you want to pad a digit, for example. `print('This number will be padded with 4 zeros: %05d ' % 1)` - this will work. `print('This number will be padded with 4 zeros: %05s ' % 1)` - this won't ` – sqram Mar 24 '20 at 16:49
  • @sqram Hi, Is there a way to change the position of John and mike without changing the position of john and mike in input? – Imtango30 Sep 15 '20 at 18:21
36

The format method was introduced in Python 2.6. It is more capable and not much more difficult to use:

>>> "Hello {}, my name is {}".format('john', 'mike')
'Hello john, my name is mike'.

>>> "{1}, {0}".format('world', 'Hello')
'Hello, world'

>>> "{greeting}, {}".format('world', greeting='Hello')
'Hello, world'

>>> '%s' % name
"{'s1': 'hello', 's2': 'sibal'}"
>>> '%s' %name['s1']
'hello'
Community
  • 1
  • 1
dansalmo
  • 11,506
  • 5
  • 58
  • 53
  • 12
    This answer would be improved if it explained that the syntax in the question was formatting text and _then_ demonstrated the newer method. That way it could stand on its own. Providing an example that was equivalent to the example in the question would also be a plus. – Steve S Jul 17 '13 at 18:03
28

%sand %d are format specifiers or placeholders for formatting strings, decimals, floats, etc.

The most common used format specifiers:

%s: string

%d: decimals

%f: float

Self explanatory code:

name = "Gandalf"
extendedName = "the Grey"
age = 84
IQ = 149.9
print('type(name): ', type(name)) # type(name): <class 'str'>
print('type(age): ', type(age))   # type(age): <class 'int'>
print('type(IQ): ', type(IQ))     # type(IQ): <class 'float'>

print('%s %s\'s age is %d with incredible IQ of %f ' %(name, extendedName, age, IQ)) # Gandalf the Grey's age is 84 with incredible IQ of 149.900000

# The same output can be printed in following ways:


print ('{0} {1}\'s age is {2} with incredible IQ of {3} '.format(name, extendedName, age, IQ))          # With the help of an older method
print ('{} {}\'s age is {} with incredible IQ of {} '.format(name, extendedName, age, IQ))          # With the help of an older method

print("Multiplication of %d and %f is %f" %(age, IQ, age*IQ)) # Multiplication of 84 and 149.900000 is 12591.600000

# Storing formattings in a string

sub1 = "python string!"
sub2 = "an arg"

a = "I am a %s" % sub1
b = "I am a {0}".format(sub1)

c = "with %(kwarg)s!" % {'kwarg':sub2}
d = "with {kwarg}!".format(kwarg=sub2)

print(a)  # "I am a python string!"
print(b)  # "I am a python string!"
print(c)  # "with an arg!"
print(d)  # "with an arg!"
Om Sao
  • 7,064
  • 2
  • 47
  • 61
14

%s indicates a conversion type of string when using Python's string formatting capabilities. More specifically, %s converts a specified value to a string using the str() function. Compare this with the %r conversion type that uses the repr() function for value conversion.

Take a look at the documentation for string formatting.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Brandon E Taylor
  • 24,881
  • 6
  • 47
  • 71
7

To answer your second question: What does this code do?...

This is fairly standard error-checking code for a Python script that accepts command-line arguments.

So the first if statement translates to: if you haven't passed me an argument, I'm going to tell you how you should pass me an argument in the future, e.g. you'll see this on-screen:

Usage: myscript.py database-name

The next if statement checks to see if the 'database-name' you passed to the script actually exists on the filesystem. If not, you'll get a message like this:

ERROR: Database database-name was not found!

From the documentation:

argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mechanical_meat
  • 163,903
  • 24
  • 228
  • 223
3

Here is a good example in Python 3.

>>> a = input("What is your name? ")
What is your name? Peter

>>> b = input("Where are you from? ")
Where are you from? DE

>>> print("So you are %s of %s." % (a, b))
So you are Peter of DE.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter Girnus
  • 2,673
  • 1
  • 19
  • 24